您的位置:首页 > 编程语言 > Java开发

Spring进阶运用

2015-11-23 23:16 381 查看
1.配置Bean的属性和依赖关系

组件与组件之间的耦合采用依赖注入管理;但对普通的JavaBean属性值,则直接在代码中设置。

1.1Bean的配置

<beans>
<bean id="唯一标识符" name="别名1,别名2" class="实现类的全限定类名"/>
</beans>


1.2设置普通属性值

<property name=" " value=" "/>


1.3配置合作者Bean

<bean id="u" class=" "/>
<bean id="user" class=" ">
<property name="userDao">
<ref bean="u"/>
</property>
<constructor-arg>
<ref bean="u">
</constructor-arg>
</bean>


!!被注入的类型只需要与注入目标中定义的类型兼容就可。


1.4注入集合值

//Set<String>
<property name="sets">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
//List<String>
<property name="lists">
<list>
<value>1</value>
<value>2</value>
</list>
</property>
//Map<String,String> <entry>中key值只能是String
<property name="maps">
<map>
<entry key="1" value="1"></entry>
<entry key="2" value="2"></entry>
</map>
</property>
<property name="maps">
<map>
<entry>
<key>
<value>1</value>
</key>
<value>1</value>
<key>
<value>2</value>
</key>
<value>2</value>
</entry>
</map>
</property>


2.管理Bean的生命周期



Spring可以管理singleton作用域Bean的生命周期,可以精确的知道该Bean何时被创建,何时初始化完成,何

时被销毁。

Spring仅负责创建prototype作用域的Bean,创建完后完全交给客户端代码管理。

两个重要生命周期时刻:postinitiation(初始化后)和predestruction(销毁前)。

2.1Spring容器中Bean的作用域

Spring3.0中支持的5种作用域:

(1)Singleton:单例模式,在容器中只有一个实例,无论多少Bean引用他,都只有一个对象;

(2)Prototype:原型模式,每次通过容器获取Bean时,都会创建一个新的实例;

(3)Request:针对每次HTTP请求都会产生一个新的Bean,仅在当前HTTP request内有效;

(4)Session:针对每次HTTP请求都会产生一个新的Bean,仅在当前HTTP session内有效;

(5)Global session:类似标准HTTP Session作用域,但仅仅在基于portlet的web应用中有效。

//scope默认为singleton
<bean id=" " class=" " scope="singleton|prototype|request|session|global session"/>


如果Bean使用了有限的资源,如数据库、网络连接等,则多个实例的创建会浪费有限的资源,此时应将Bean设置为
singleton。


2.2Bean的实例化

当一个Bean实例化时,往往需要执行一些初始化工作;不再使用时,需要从容器中删除他。

(1)指定初始化方法

<bean id="bean1" class="com.bean.simpleBean" init-method="init"
<property name="name" value="xiaoming"/>
</bean>


Spring完成依赖注入后,自动调用init()方法。


(2)实现InitializingBean接口(侵入式设计,不推荐使用)

一旦某个Bean实现了InitializingBean接口,那么这个Bean的代码就与Spring耦合到一起了。该接口只定义

了一个afterPropertiesSet方法。

凡是继承了InitializingBean接口的类,初始化Bean时都会执行其afterPropertiesSet方法。

!!可以和指定初始化方法 同时使用,此时先执行afterPropertiesSet()方法,再执行init-method属性指定

方法。

Spring容器可以自动检测Bean中是否实现了特定生命周期接口,若实现某个生命周期接口,则需执行相应

的生命周期方法。

2.3Bean的销毁

Spring提供了两种方法在Bean实例销毁之前执行指定的动作:使用destroy-method属性和实现

DisposableBean接口。

(1)使用关闭钩子(shutdown hook)

只需要调用在AbstractApplicationContext中提供的registerShutdownHook()方法

public static void main(String[] args){
AbstractApplicationContext ctx = new
ClassPathXmlApplicationContext("beans.xml");
ctx.getBean(" ");
//为Spring容器注册关闭钩子
ctx.registerShutdownHook();
}


程序会在退出JVM之前关闭Spring ApplicationContext容器,并在关闭之前调用singleton作用域中Bean的
析构回调方法。


(2)Bean销毁时执行析构方法

可以在Bean中定义一个普通的析构方法,然后在XML配置文件中通过destroy-method属性指定其方法

名。Spring会在销毁单例前调用此方法执行一些清理和释放工作。

<bean id="bean1" class="com.bean.simpleBean" destroy-method="close"
<property name="name" value="xiaoming"/>
</bean>
//Spring会在销毁bean1实例前自动调用simpleBean类中的close()方法。


(3)实现DisposableBean接口(侵入式设计)

该接口只有一个方法:void destroy() throws Exception,Bean实例被销毁前执行的方法。

2.4使用方法注入

singleton Bean依赖的一直是最开始(初始化时)的Bean实例。

lookup方法注入利用了Spring容器重写Bean中抽象方法或具体方法的能力,从而返回指定名字的Bean实

例,常用来获取一个non-singleton对象。

!!Spring方法注入需要用到CGLIB的动态代理功能,需要将CGLIB库的JAR包导入到项目中。

public abstract MyHelper getMyHelper();
@Override
public MyHelper getHelper(){
return getMyHelper();
}


<bean id="helper" class="com.deciphering.bean.MyHelper" scope="prototype">
</bean>
<bean id="abstractLookupBean" class="com.deciphering.bean.AbstractLookupDemo">
<lookup-method name="getMyHelper" bean="helper"/>
</bean>


3.让Bean可以感知Spring容器

3.1使用BeanNameAware接口

该接口仅有一个方法:setBeanName(String name),name参数为Bean的id.Bean属性设置完后,初始化回调方法之前,setBeanName回调方法会先被调用。

public class SimpleBean implements InitializingBean, BeanNameAware{
private String beanName;
...
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
System.out.println("回调setBeanName方法获得BeanName "+ beanName);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(beanName+"初始化,调用afterPropertiesSet()...");
}
}
//先调用setBeanName(String beanName),再调用afterPropertiesSet()


3.2使用BeanFactoryAware接口、ApplicationContextAware接口

BeanFactoryAware接口只有一个方法:setBeanFactory(BeanFactory beanFactory);

实现该接口让Bean拥有了直接访问容器的能力,导致代码和Spring接口耦合在一起

public class SimpleBean implements InitializingBean, BeanFactoryAware{
private BeanFactory Factory;
...
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.Factory = beanFactory;
System.out.println("获得容器: "+Factory);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化完成,调用afterPropertiesSet()...");
}
}
//先调用setBeanFactory(BeanFactory beanFactory),再调用afterPropertiesSet()


!!Spring容器完成依赖关系注入之后会回调setBeanFactory()方法,此时应用程序可获得创建该Bean的BeanFactory引用,程序可以保存该引用并利用其做一些处理。
另外,类似,还有ApplicationContextAware接口,可获得ApplicationContext容器的引用。


4.Spring国际化支持

getMessage()的重载方法:

getMessage(String,Object[],Locale);

getMessage(String,Object[],String Locale);

getMessage(MessageSourceResolvable,Locale)

public class SimpleBean {
public static void main(String[] args){
//实例化ApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
String [] a = {"读者"};
//使用getMessage方法获得本地化信息。
//返回计算机环境默认的Locale
String hello = ctx.getMessage("hello", a, Locale.getDefault());
Object[] b = { new Date() };
String now = ctx.getMessage("now", b, Locale.getDefault());
//将两条本地化信息打印出来
System.out.println(hello);
System.out.println(now);

//认为设置成英文环境
hello = ctx.getMessage("hello", a, Locale.US);
now = ctx.getMessage("now", b, Locale.US);
//将两条英文信息打印出来
System.out.println(hello);
System.out.println(now);

//认为设置成中文环境
hello = ctx.getMessage("hello", a, Locale.CHINA);
now = ctx.getMessage("now", b, Locale.CHINA);
//将两条中文信息打印出来
System.out.println(hello);
System.out.println(now);
}
}
//即使在英文环境下,“读者”也不能变成英文,因为是写在代码中而不是从资源文件中获取的。


<!-- id="messageSource"不变 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" >
<list>
<value>message</value>
<!--
如果有多个资源文件,全部列举在此
-->
</list>
</property>
</bean>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring bean 管理