Bean之间的关系:继承和依赖。
继承Bean配置
Spring允许继承bean的配置,被继承的bean称为父bean,继承这个父bean的Bean称为子Bean。
子Bean从父Bean中继承配置,包括Bean的属性配置。
子Bean也可以覆盖从父Bean继承过来的配置。
父Bean可以作为配置模板,也可以作为Bean实例,若只想把父Bean作为模板,可以设置<bean>的abstract属性为true,这样Spring将不会实例化这个bean。(抽象Bean,抽象Bean不能被实例化,只能被继承)
并不是<bean>元素里的所有属性都会被继承,比如:autowire,abstract等。
也可以忽略父Bean的class属性,让子Bean指定自己的类,而共享相同的属性配置。但此时abstract必须为true。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="logan.spring.study.autowire.Address" p:city="Beijing" p:street="WuDaoKou"></bean> <bean id="address2" class="logan.spring.study.autowire.Address" p:city="Beijing" p:street="DaZhongSi"></bean> </beans>
package logan.spring.study.relation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import logan.spring.study.autowire.Address; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-relation.xml"); Address address = (Address) ctx.getBean("address"); System.out.println(address); address = (Address) ctx.getBean("address2"); System.out.println(address); } }
下面是输出结果:
五月 20, 2017 4:03:58 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Sat May 20 16:03:58 CST 2017]; root of context hierarchy 五月 20, 2017 4:03:58 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-relation.xml] Address [city=Beijing, street=WuDaoKou] Address [city=Beijing, street=DaZhongSi]
可以看到两个address的内容大部分都是一样的,所以,我们可以如下使用关系,让第二个address继承第一个address
如下配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="logan.spring.study.autowire.Address" p:city="Beijing1" p:street="WuDaoKou"></bean> <bean id="address2" p:street="DaZhongSi" parent="address"></bean> </beans>
下面是输出结果
五月 20, 2017 4:08:07 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Sat May 20 16:08:07 CST 2017]; root of context hierarchy 五月 20, 2017 4:08:07 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-relation.xml] Address [city=Beijing1, street=WuDaoKou] Address [city=Beijing1, street=DaZhongSi]
下面看Bean之间的依赖关系
Spring允许用户通过depends-on属性设定Bean前置依赖的Bean,前置依赖的Bean会在本Bean实例化之前创建好。
如果前置依赖于多个Bean,则可以通过都好,空格的方式配置Bean的名称。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="logan.spring.study.autowire.Address" p:city="Beijing1" p:street="WuDaoKou"></bean> <bean id="address2" p:street="DaZhongSi" parent="address"></bean> <bean id="person" class="logan.spring.study.autowire.Person" p:name="Tom" p:address-ref="address"></bean> </beans>
package logan.spring.study.relation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import logan.spring.study.autowire.Address; import logan.spring.study.autowire.Person; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-relation.xml"); Address address = (Address) ctx.getBean("address"); System.out.println(address); address = (Address) ctx.getBean("address2"); System.out.println(address); Person person = (Person) ctx.getBean("person"); System.out.println(person); } }
下面是输出结果
五月 20, 2017 4:23:24 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Sat May 20 16:23:24 CST 2017]; root of context hierarchy 五月 20, 2017 4:23:25 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-relation.xml] Address [city=Beijing1, street=WuDaoKou] Address [city=Beijing1, street=DaZhongSi] Person [name=Tom, address=Address [city=Beijing1, street=WuDaoKou], car=null]
可以看到car是null,如果我必须要car不是null,也就是说person依赖于null,那么如何做?
如下做法:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="logan.spring.study.autowire.Address" p:city="Beijing1" p:street="WuDaoKou"></bean> <bean id="address2" p:street="DaZhongSi" parent="address"></bean> <bean id="person" class="logan.spring.study.autowire.Person" p:name="Tom" p:address-ref="address" depends-on="car"></bean> </beans>
输出错误结果
五月 20, 2017 4:27:50 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Sat May 20 16:27:50 CST 2017]; root of context hierarchy 五月 20, 2017 4:27:50 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [beans-relation.xml] 五月 20, 2017 4:27:50 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh 警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'car' available Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'car' available at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687) at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296) 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 logan.spring.study.relation.Main.main(Main.java:14)
如下配置就不会报错
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="logan.spring.study.autowire.Address" p:city="Beijing1" p:street="WuDaoKou"></bean> <bean id="address2" p:street="DaZhongSi" parent="address"></bean> <bean id="car" class="logan.spring.study.autowire.Car" p:brand="Audi" p:price="300000"></bean> <bean id="person" class="logan.spring.study.autowire.Person" p:name="Tom" p:address-ref="address" depends-on="car"></bean> </beans>