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注解的案例来说明:
还记得上一篇文章需要的几个类吗,这里我们再用一次。
准备好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"); } }
根据不同的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: 构造器参数具体的索引
//还是给一个简单运行的案例//改造HelloWordImp2public 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的配置还有更深入的内容,等待我们去探索。
共同学习,写下你的评论
评论加载中...
作者其他优质文章