Bean 之间的关系:继承、依赖。
Bean 继承:
- Spring 允许继承 bean 的配置 , 被继承的 bean 称为父 bean , 继承这个父 bean 的 bean 称为子 bean。
- 子 bean 从父 bean 中继承配置 , 包括 bean 的属性配置。
- 子 bean 也可以覆盖从父 bean 继承过来的配置。
- 父 bean 可以作为配置模板 , 也可以作为 bean 实例。若只想把父 bean 作为模板 , 可以设置 <bean> 的 abstract 属性为 true , 这样 IOC容器将不会实例这个 bean。
- 并不是 <bean> 元素里的所有属性都会被继承。比如: autowire , abstract 等。
- 父 bean 的 class 属性可以忽略 , 让子 bean 指定自己的类 , 而共享相同的属性配置。但此时 abstract 必须设为 true。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="address" class="com.itdoc.spring.extendsinfo.Address" p:city="DaLian" p:street="ShaHeKou"/> 8 9 <bean id="address1" class="com.itdoc.spring.extendsinfo.Address" p:street="GanJingZi" parent="address"/> 10 11 </beans>
1 package com.itdoc.spring.extendsinfo; 2 3 /** 4 * http://www.cnblogs.com/goodcheap 5 * 6 * @author: Wáng Chéng Dá 7 * @create: 2017-03-01 20:48 8 */ 9 public class Address { 10 11 private String city; 12 13 private String street; 14 15 public String getCity() { 16 return city; 17 } 18 19 public void setCity(String city) { 20 this.city = city; 21 } 22 23 public String getStreet() { 24 return street; 25 } 26 27 public void setStreet(String street) { 28 this.street = street; 29 } 30 31 @Override 32 public String toString() { 33 return "Address{" + 34 "city=‘" + city + ‘\‘‘ + 35 ", street=‘" + street + ‘\‘‘ + 36 ‘}‘; 37 } 38 }
1 package com.itdoc.spring.extendsinfo; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 /** 7 * http://www.cnblogs.com/goodcheap 8 * 9 * @author: Wáng Chéng Dá 10 * @create: 2017-03-01 20:55 11 */ 12 public class Main { 13 14 public static void main(String[] args) { 15 ApplicationContext app = new ClassPathXmlApplicationContext("beans_extends.xml"); 16 Address address = (Address) app.getBean("address"); 17 System.out.println(address); 18 19 System.out.println("-------------------"); 20 address = (Address) app.getBean("address1"); 21 System.out.println(address); 22 23 } 24 }
控制台输出:
Address{city=‘DaLian‘, street=‘ShaHeKou‘} ------------------- Address{city=‘DaLian‘, street=‘GanJingZi‘} |
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="address" class="com.itdoc.spring.extendsinfo.Address" p:city="DaLian" p:street="ShaHeKou" abstract="true"/> 8 9 <bean id="address1" class="com.itdoc.spring.extendsinfo.Address" p:street="GanJingZi" parent="address"/> 10 11 </beans>
控制台输出:
Exception in thread "main" org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name ‘address‘: Bean definition is abstract at org.springframework.beans.factory.support.AbstractBeanFactory.checkMergedBeanDefinition(AbstractBeanFactory.java:1321) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:285) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) at com.itdoc.spring.extendsinfo.Main.main(Main.java:16) |
原因:address 成为了模板 bean , 不可以实例化。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="address" p:city="DaLian" p:street="ShaHeKou"/> 8 9 <bean id="address1" class="com.itdoc.spring.extendsinfo.Address" p:street="GanJingZi" parent="address"/> 10 11 </beans>
1 package com.itdoc.spring.extendsinfo; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 /** 7 * http://www.cnblogs.com/goodcheap 8 * 9 * @author: Wáng Chéng Dá 10 * @create: 2017-03-01 20:55 11 */ 12 public class Main { 13 14 public static void main(String[] args) { 15 ApplicationContext app = new ClassPathXmlApplicationContext("beans_extends.xml"); 16 Address address = (Address) app.getBean("address1"); 17 System.out.println(address); 18 19 } 20 }
控制台输出:
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘address‘ defined in class path resource [beans_extends.xml]: Instantiation of bean failed; nested exception is java.lang.IllegalStateException: No bean class specified on bean definition Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘address‘ defined in class path resource [beans_extends.xml]: Instantiation of bean failed; nested exception is java.lang.IllegalStateException: No bean class specified on bean definition at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at com.itdoc.spring.extendsinfo.Main.main(Main.java:15) Caused by: java.lang.IllegalStateException: No bean class specified on bean definition at org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClass(AbstractBeanDefinition.java:372) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:66) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147) ... 13 more |
原因:父 bean 中的 class 属性忽略 , 该 bean 必须是 abstract="true" 的。
Bean 依赖:
- Spring 允许用户通过 depends-on 属性设定 bean 前置依赖的 bean , 前置依赖的 bean 会在本 bean 实例化前创建好。
- 如果前置依赖于多个 bean , 则可以通过逗号或空格的方式配置 bean 的名称。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="person" class="com.itdoc.spring.extendsinfo.Person" p:name="华崽儿" p:car-ref="car" p:address-ref="address"/> 8 <bean id="address" class="com.itdoc.spring.extendsinfo.Address" p:city="DaLian" p:street="ShaHeKou"/> 9 <bean id="car" class="com.itdoc.spring.beans.Car" p:brand="8手奥拓" p:price="3000" p:maxSpeed="120"/> 10 11 </beans>
1 package com.itdoc.spring.extendsinfo; 2 3 import com.itdoc.spring.beans.Car; 4 5 /** 6 * http://www.cnblogs.com/goodcheap 7 * 8 * @author: Wáng Chéng Dá 9 * @create: 2017-03-01 20:47 10 */ 11 public class Person { 12 13 private String name; 14 15 private Address address; 16 17 private Car car; 18 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public Address getAddress() { 28 return address; 29 } 30 31 public void setAddress(Address address) { 32 this.address = address; 33 } 34 35 public Car getCar() { 36 return car; 37 } 38 39 public void setCar(Car car) { 40 this.car = car; 41 } 42 43 public Person() { 44 System.out.println("I am Person Constructor..."); 45 } 46 47 @Override 48 public String toString() { 49 return "Person{" + 50 "name=‘" + name + ‘\‘‘ + 51 ", address=" + address + 52 ", car=" + car + 53 ‘}‘; 54 } 55 }
1 package com.itdoc.spring.extendsinfo; 2 3 /** 4 * http://www.cnblogs.com/goodcheap 5 * 6 * @author: Wáng Chéng Dá 7 * @create: 2017-03-01 20:48 8 */ 9 public class Address { 10 11 private String city; 12 13 private String street; 14 15 public String getCity() { 16 return city; 17 } 18 19 public void setCity(String city) { 20 this.city = city; 21 } 22 23 public String getStreet() { 24 return street; 25 } 26 27 public void setStreet(String street) { 28 this.street = street; 29 } 30 31 public Address() { 32 System.out.println("I am Address Constructor..."); 33 } 34 35 @Override 36 public String toString() { 37 return "Address{" + 38 "city=‘" + city + ‘\‘‘ + 39 ", street=‘" + street + ‘\‘‘ + 40 ‘}‘; 41 } 42 }
1 package com.itdoc.spring.beans; 2 3 /** 4 * 集合中的对象 5 * http://www.cnblogs.com/goodcheap 6 * 7 * @author: Wáng Chéng Dá 8 * @create: 2017-02-28 19:56 9 */ 10 public class Car { 11 12 private String brand; 13 14 private double price; 15 16 private int maxSpeed; 17 18 public String getBrand() { 19 return brand; 20 } 21 22 public void setBrand(String brand) { 23 this.brand = brand; 24 } 25 26 public double getPrice() { 27 return price; 28 } 29 30 public void setPrice(double price) { 31 this.price = price; 32 } 33 34 public int getMaxSpeed() { 35 return maxSpeed; 36 } 37 38 public void setMaxSpeed(int maxSpeed) { 39 this.maxSpeed = maxSpeed; 40 } 41 42 public Car() { 43 System.out.println("I am Car Constructor..."); 44 } 45 46 @Override 47 public String toString() { 48 return "Car{" + 49 "brand=‘" + brand + ‘\‘‘ + 50 ", price=" + price + 51 ", maxSpeed=" + maxSpeed + 52 ‘}‘; 53 } 54 }
1 package com.itdoc.spring.extendsinfo; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 /** 7 * http://www.cnblogs.com/goodcheap 8 * 9 * @author: Wáng Chéng Dá 10 * @create: 2017-03-01 20:55 11 */ 12 public class Main { 13 14 public static void main(String[] args) { 15 ApplicationContext app = new ClassPathXmlApplicationContext("beans_extends.xml"); 16 Person person = (Person) app.getBean("person"); 17 System.out.println(person); 18 19 } 20 }
控制台输出:
I am Person Constructor... I am Address Constructor... I am Car Constructor... Person{name=‘华崽儿‘, address=Address{city=‘DaLian‘, street=‘ShaHeKou‘}, car=Car{brand=‘8手奥拓‘, price=3000.0, maxSpeed=120}} |
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="person" class="com.itdoc.spring.extendsinfo.Person" p:name="华崽儿" p:car-ref="car" p:address-ref="address" depends-on="car, address"/> 8 9 <bean id="address" class="com.itdoc.spring.extendsinfo.Address" p:city="DaLian" p:street="ShaHeKou"/> 10 11 <bean id="car" class="com.itdoc.spring.beans.Car" p:brand="8手奥拓" p:price="3000" p:maxSpeed="120"/> 12 13 </beans>
控制台输出:
I am Car Constructor... I am Address Constructor... I am Person Constructor... Person{name=‘华崽儿‘, address=Address{city=‘DaLian‘, street=‘ShaHeKou‘}, car=Car{brand=‘8手奥拓‘, price=3000.0, maxSpeed=120}} |
根据控制台输出我们不难看出 bean 的初始化顺序发生了改变 , 前置依赖的 bean 会在本 bean 实例化前创建好。
时间: 2024-10-02 02:24:57