首页 > 代码库 > Spring入门第七课

Spring入门第七课

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>

 

Spring入门第七课