(9)spring更多di知识

来源:互联网 发布:淘宝新版质保金好退吗 编辑:程序博客网 时间:2024/06/07 06:43

1、延迟初始化bean,lazy-init="true"

正常Spring容器会在创建容器时提前初始化“singleton”作用域的bean。

在bean的标签上指定lazy-init="true"即可延迟初始化bean,通常会在第一次使用的时候初始化,或者作为其它bean依赖对象注入时,随着其它bean的初始化而被初始化

<bean id="hello" class="shuai.spring.study.HelloImpl" lazy-init="true"/>

验证:

修改HelloImpl.java

package shuai.spring.study;public class HelloImpl implements HelloApi {public HelloImpl() {System.out.println("调用无参构造");}@Overridepublic void sayHello() {System.out.println("Hello World!");}}

修改测试方法

package shuai.spring.test;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class HelloTest {@Testpublic void testHelloWorld() {@SuppressWarnings({ "unused", "resource" })ApplicationContext context = new ClassPathXmlApplicationContext("HelloWorld.xml");}}
配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd">   <bean id="hello" class="shuai.spring.study.HelloImpl"/></beans>

这时候只是初始化一些容器

测试结果:调用无参构造

可以打印无参构造里的话,说明bean已经初始化了。

如果配置文件改为

<bean id="hello" class="shuai.spring.study.HelloImpl" lazy-init="true"/>

将不会打印任何内容,说明bean没初始化。

测试方法改为

@SuppressWarnings("resource")ApplicationContext context = new ClassPathXmlApplicationContext("HelloWorld.xml");HelloApi helloApi = context.getBean("hello", HelloApi.class);helloApi.sayHello();

测试结果:

调用无参构造
Hello World!

此时已经使用bean了,所以使不使用延迟初始化都会初始化了

2、使用depends-on

指定bean的初始化及销毁顺序,使用depends-on,如果有多个值可以用逗号,分号,空格分割

<bean id="hello1" class="shuai.spring.study.HelloImpl"/>   <bean id="hello" class="shuai.spring.study.HelloImpl4" depends-on="hello1">   <property name="helloApi">   <ref bean="hello1"/>   </property>   </bean>

如果一个bean的某个属性是其它bean,比如hello这个bean的helloApi属性要引用另一个bean,hello1,就可以在hello这个bean里加一个属性depends-on=“hello1”,depends-on指定的bean会在当前bean初始化前先初始化,并且在当前bean销毁后销毁。

修改HelloImpl.java

package shuai.spring.study;public class HelloImpl implements HelloApi {private String message;public HelloImpl() {System.out.println("调用无参构造======helloImpl");}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public void init() {System.out.println("初始化helloImpl======" + message);}public void destory() {System.out.println("销毁helloImpl======");}@Overridepublic void sayHello() {System.out.println("Hello World!");}}

修改HelloImpl4.java

package shuai.spring.study;public class HelloImpl4 implements HelloApi {private HelloApi helloApi;public HelloImpl4() {System.out.println("调用无参构造======helloImpl4");}public HelloApi getHelloApi() {return helloApi;}public void setHelloApi(HelloApi helloApi) {this.helloApi = helloApi;}public void init() {System.out.println("初始化helloImpl4======");}public void destory() {System.out.println("销毁helloImpl4======");}@Overridepublic void sayHello() {helloApi.sayHello();}}

修改测试类

package shuai.spring.test;import org.junit.Test;import org.springframework.context.support.AbstractApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import shuai.spring.study.HelloApi;public class HelloTest {@Testpublic void testHelloWorld() {@SuppressWarnings("resource")AbstractApplicationContext context = new ClassPathXmlApplicationContext("HelloWorld.xml");// 一点要注册销毁回调,否则我们定义的销毁方法不执行context.registerShutdownHook();HelloApi helloApi = context.getBean("hello", HelloApi.class);helloApi.sayHello();}}

修改配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd">   <bean id="hello1" class="shuai.spring.study.HelloImpl" init-method="init" destroy-method="destory">   <property name="message"><value>hello helloImpl</value></property>   </bean>      <bean id="hello" class="shuai.spring.study.HelloImpl4" init-method="init" destroy-method="destory" depends-on="hello1">   <property name="helloApi">   <ref bean="hello1"/>   </property>   </bean></beans>

输出结果:

调用无参构造======helloImpl
初始化helloImpl======hello helloImpl
调用无参构造======helloImpl4
初始化helloImpl4======
Hello World!
销毁helloImpl4======
销毁helloImpl======

init-method="方法名":初始化方法,根据测试结果也可以看出,是在setter注入后执行的。

destroy-method="方法名":指定销毁方法,需要在测试方法里注册销毁回调,不然不执行,context.registerShutdownHook();【摘抄】只有“singleton”作用域能销毁,“prototype”作用域的一定不能,其他作用域不一定能

具体,看开涛老师的http://jinnianshilongnian.iteye.com/blog/1415461

3、自动装配

修改HelloImpl4.java

package shuai.spring.study;public class HelloImpl4 implements HelloApi {private HelloApi helloApi;public HelloApi getHelloApi() {return helloApi;}public void setHelloApi(HelloApi helloApi) {this.helloApi = helloApi;}@Overridepublic void sayHello() {helloApi.sayHello();}}


正常一个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"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="hello1" class="shuai.spring.study.HelloImpl" />   <bean id="hello" class="shuai.spring.study.HelloImpl4" >   <property name="helloApi">   <ref bean="hello1"/>   </property>   </bean></beans>

如果自动注入,使用autowire属性,属性的值有四种,“no”、“byName ”、“byType”、“constructor”、“default”

no:就是不支持自动装配,就像上面那么写

byName:根据名字自动装配

<bean id="helloApi" class="shuai.spring.study.HelloImpl" /><bean id="hello" class="shuai.spring.study.HelloImpl4" autowire="byName"/>

这里的名字是根据setter方法的,比如,HelloImpl4.java里的方法名字是setHelloApi,那就要找一个bean的id(name也行,就是标识)是helloApi注入,注意下,不是根据属性的真实名字,是根据setter方法的名字。

byType:根据类型

<bean id="hello1" class="shuai.spring.study.HelloImpl" /><bean id="hello2" class="shuai.spring.study.HelloImpl" /><bean id="hello3" class="shuai.spring.study.HelloImpl" /><bean id="hello" class="shuai.spring.study.HelloImpl4" autowire="byType"/>

这里的类型,也是setter方法需要传入的类型
但是这样是会出错的,因为hello1、hello2、hello3类型都符合,容器会不知道选哪个,所以一定要选出一个来,两种方式,1使用属性autowire-candidate放弃自动装配的候选者,2使用属性primary指定为首选。

所以,可以改为

<bean id="hello1" class="shuai.spring.study.HelloImpl" autowire-candidate="false"/><bean id="hello2" class="shuai.spring.study.HelloImpl" autowire-candidate="false"/><bean id="hello3" class="shuai.spring.study.HelloImpl" /><bean id="hello" class="shuai.spring.study.HelloImpl4" autowire="byType"/>

或者

<bean id="hello1" class="shuai.spring.study.HelloImpl" primary="true"/><bean id="hello2" class="shuai.spring.study.HelloImpl" /><bean id="hello3" class="shuai.spring.study.HelloImpl" /><bean id="hello" class="shuai.spring.study.HelloImpl4" autowire="byType"/>

constructor:根据构造方法的参数的类型

为HelloImpl4.java添加一个有参构造

public HelloImpl4() {}public HelloImpl4(HelloApi helloApi) {this.helloApi = helloApi;}


配置文件修改为

<bean id="hello1" class="shuai.spring.study.HelloImpl" primary="true"/><bean id="hello2" class="shuai.spring.study.HelloImpl" /><bean id="hello3" class="shuai.spring.study.HelloImpl" /><bean id="hello" class="shuai.spring.study.HelloImpl4" autowire="constructor"/>

default:使用default要在beans里配置default-autowire属性

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd"        default-autowire="byType"><bean id="hello1" class="shuai.spring.study.HelloImpl" primary="true"/><bean id="hello2" class="shuai.spring.study.HelloImpl" /><bean id="hello3" class="shuai.spring.study.HelloImpl" />   <bean id="hello" class="shuai.spring.study.HelloImpl4" autowire="default"/></beans>

也可以用autwire覆盖default-autowire


阅读全文
0 0
原创粉丝点击