Spring Bean配置

作者: Real_man | 来源:发表于2018-05-20 09:59 被阅读49次

    Spring Bean管理

    Spring的核心在于Ioc,我们上一篇已经提到了Ioc的概念,把对象的控制权较给容器来管理。在Spring中,凡是被Spring创建和管理的对象都叫做Bean。

    Bean

    Spring管理的Bean,一般是由你提供的配置来创建,如Java配置,注解配置,XML配置。在容器内部,这些Bean表现为BeanDefinition对象。

    Bean的配置

    基于XML的配置

    在xml中,我们可以更了解Bean的配置,一个配置案例如下:


    常见xml配置

    分别解说各个参数的作用:

    • class: 要实例化的类。所谓的bean在内存中就是实例化后的对象。class指的是要实例化那个类。
    • name: Bean的名称,便于记忆
    • scope: 下面会提到
    • constructor arguments: 构造器参数
    • properties 属性
    • autowiring模式,Bean依赖其它Bean时候的模式
    • lazy-initialization 懒加载模式
    • initialization 初始化方法
    • destruction 销毁方法

    直接拿一个XML注解的案例来说明:
    还记得上一篇文章需要的几个类吗,这里我们再用一次。

    1. 准备好Java对象
    public interface HelloWord {
        void sayHello();
    }
    
    public class HelloWordImpl1 implements HelloWord {
        @Override
        public void sayHello() {
            System.out.println("hello1");
        }
    }
    
    public class HelloWordImpl2 implements HelloWord {
        @Override
        public void sayHello() {
            System.out.println("hello2");
        }
    }
    
    1. 根据不同的XML配置,获得不同的结果

    2.1 scope的作用

    scope为prototype时,每次从容器中获取bean,相应的对象都会重新实例化一次,也就是每次拿到的都是新创建的对象。
    scope为singleton的时候,bean一直在容器中存在,直接容器销毁之前销毁,每次获取bean,获取到的是同一个bean

    
    //准备好App文件
    
    public class App {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
            HelloWord helloWord = applicationContext.getBean(HelloWord.class);
            HelloWord helloWord2 = applicationContext.getBean(HelloWord.class);
            helloWord.sayHello();
            System.out.println(helloWord2);
        }
    }
    
    <bean id="helloworld" class="me.aihe.HelloWordImpl2" scope="prototype"/>
    //运行结果
    me.aihe.HelloWordImpl2@6a2bcfcb
    me.aihe.HelloWordImpl2@4de8b406
    
    <bean id="helloworld" class="me.aihe.HelloWordImpl2" scope="singleton"/>
    //运行结果
    me.aihe.HelloWordImpl2@6d8a00e3
    me.aihe.HelloWordImpl2@6d8a00e3
    
    

    Spring默认bean的scope为singleton。

    2.2 construct-arg参数
    这个参数是构造bean对象的时候,提供构造参数
    [图片上传失败...(image-d2cf54-1526781442058)]

    • ref指的是,当构造某个bean的时候,这个bean依赖其它的bean,使用ref来指向依赖的bean
    • type: 构造器参数中,精确的类型是什么,String或其它等等
    • index: 构造器参数具体的索引
    //还是给一个简单运行的案例
    //改造HelloWordImp2
    public class HelloWordImpl2 implements HelloWord {
    
        String str;
        
        public HelloWordImpl2(String str) {
            this.str = str;
            System.out.println("实例化str:" + str);
        }
    
        public void sayHello() {
            System.out.println("hello2");
        }
    }
    //XML配置
       <bean id="helloworld" class="me.aihe.HelloWordImpl2">
            <constructor-arg type="java.lang.String" value="你好" />
        </bean>
         <bean id="helloworld" class="me.aihe.HelloWordImpl2">
            <constructor-arg index="0" value="你好" />
        </bean>
        <bean id="helloworld" class="me.aihe.HelloWordImpl2">
            <constructor-arg name="str" value="你好" />
        </bean>
        
    // 以上三个bean只需要其中一个就好了,这里演示的是三个的运行结果都是一样的
    //运行结果都是
    实例化str:你好
    me.aihe.HelloWordImpl2@d8355a8
    me.aihe.HelloWordImpl2@d8355a8
    

    2.3 property属性
    property主要配置Java对象中有setter和getter方法的属性。

    2.4 autowiring模式,保持默认就好,bean解析的方式,byType,byName

    2.5 lazy-init赖加载模式
    当设置为true的时候,只有在我们需要这个对象的时候,才会被实例化。

    public class App {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
            System.out.println("初始化applicationContext完成");
            HelloWord helloWord = applicationContext.getBean(HelloWord.class);
            System.out.println(helloWord);
        }
    }
    
    
    public class HelloWordImpl2 implements HelloWord {
        
        public HelloWordImpl2() {
            System.out.println("实例化中");
        }
        public void sayHello() {
            System.out.println("hello2");
        }
    }
    
    <bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="true" />
    // 运行结果
    初始化applicationContext完成
    实例化中
    me.aihe.HelloWordImpl2@573f2bb1
    
    <bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" />
    //运行结果
    实例化中
    初始化applicationContext完成
    me.aihe.HelloWordImpl2@6d8a00e3
    
    

    可以看到,使用lay-init为true之后,在应用初始化完成后,只有再调用的时候才会实例化具体的bean。而设置为false则在初始化applicationContext的时候就实例化了。

    2.6 init-method
    在实例化该对象的后,调用此方法

    <bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" init-method="sayHello"/>
    
    //运行结果
    实例化中
    hello2
    初始化applicationContext完成
    me.aihe.HelloWordImpl2@6d8a00e3
    

    2.7 destroy-method
    容器销毁该bean的时候,调用此方法

    public class App {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
            System.out.println("初始化applicationContext完成");
            HelloWord helloWord = applicationContext.getBean(HelloWord.class);
            System.out.println(helloWord);
            ((ClassPathXmlApplicationContext) applicationContext).destroy();
        }
    }
    
    public class HelloWordImpl2 implements HelloWord {
    
    
        public HelloWordImpl2() {
            System.out.println("实例化中");
        }
        public void sayHello() {
            System.out.println("hello2");
        }
    
        public void sayGoodBye(){
            System.out.println("拜拜");
        }
    }
    
    <bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" init-method="sayHello" destroy-method="sayGoodBye"/>
    
    // 运行结果
    实例化中
    hello2
    初始化applicationContext完成
    me.aihe.HelloWordImpl2@6d8a00e3
    拜拜
    

    基于注解与基于Java的配置

    了解了XML配置之后,注解的配置更加简单,关键的几个注解如下

    • @Bean, 可以指定name,init-method,destroy-method,autowire

    • @Lazy 指定bean是否要懒加载

    • @Scope 指定scope

    • @Primary 当有多个bean类型相同的时候,指定优先使用带有@primary的bean,有多个@primary标记类型相同的bean的时候,会报错

    • @Component,@controller,@Service,@Reposotory 标记某个对象为bean

    Bean的扫描

    在XML配置中

    // 开启注解配置
    <context:annotation-config />
    // 扫描bean所在的包
    <context:component-scan base-package="me.aihe" />
    

    Java配置

    @ComponentScan(value = "me.aihe")
    

    小结

    这篇文章主要讲了Bean的常见配置,Bean的配置还有更深入的内容,等待我们去探索。

    相关文章

      网友评论

        本文标题:Spring Bean配置

        本文链接:https://www.haomeiwen.com/subject/pbvzdftx.html