1、
package spring.beansandcontext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
//如果被装配的Bean实现了相应的接口,就可以在Bean中获得相应的信息。,或者进行某些操作。
public class HelloServiceImpl implements HelloService,
//以下同时为接口的调用的顺序
BeanNameAware,//获得Bean名,也就是<Bean>标签的id属性值。
BeanClassLoaderAware,//获得装载过程中的ClassLoader对象。
BeanFactoryAware,//获得BeanFactory对象
ApplicationContextAware,//获得ApplicationContext对象
InitializingBean, //在Bean的所有属性设置完后,并且在调用完上面接口的方法后,调用此接口的afterPropertiesSet方法
DisposableBean //当销毁Bean时,调用此接口的destroy方法
{
private String greeting;
public String getGreeting() {
// TODO Auto-generated method stub
return "hello " + greeting;
}
// 以下同时为方法的调用的顺序
public void setGreeting(String greeting) {
this.greeting = greeting;
System.out.println("setGreeting 设置greeting属性值");
}
public void setBeanName(String name) {
System.out.println("BeanNameAware 接口方法 获得Bean名,也就是<Bean>标签的id属性值:" + name);
}
public void setBeanClassLoader(ClassLoader arg0) {
System.out.println("BeanClassLoaderAware接口方法 获得装载过程中的ClassLoader对象:" + arg0);
}
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("BeanFactoryAware接口方法 获得BeanFactory对象:" + arg0);
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println("ApplicationContextAware接口方法 获得ApplicationContext对象:" + applicationContext);
}
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean接口方法 afterPropertiesSet");
}
public void initMethod() {
System.out.println("<bean>标签的init-Method属性指定的方法,此方法在afterPropertiesSet()之后调用");
}
public void destroy() throws Exception {
System.out.println("DisposableBean 接口方法 destroy");
}
public void destroyMethod() {
System.out.println("<bean>标签的destroy-Method属性指定的方法,此方法在destroy()之后调用");
}
}
2、Spring的InitializingBean和init-method
Spring的InitializingBean和init-method
Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;否则每次创建bean时afterPropertiesSet方法都会被重新调用.
Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下不建议直接实现InitializingBean,而是用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法,这可以在一个bean的配置文件中通过init-method声明:
<bean id="testBean" class="TestClass" init-method="initialize"/>
spring要求这个init-method方法是一个无参数的方法
如果一个bean同时实现了这两种方式的初始化配置,则spring会先调用afterPropertiesSet方法,然后通过反射调用init-method,任何一个方法出错都会导致spring创建bean失败.如果afterPropertiesSet方法调用失败,也不会再继续执行init-mehtod方法.
init-method属性用于指定自定义初始化方法
---------------------------------
引用配置文件的值
<!-- cache.properties中定义memcache.cache_prefix=sns\:2\: -->
<bean id="globalCacheManager" class="com.xiaonei.wap.framework.cache.GlobalCacheManager">
<property name="memCacheManager" ref="memCacheManger" />
<property name="cachePrefix" value="${memcache.cache_prefix}" />
</bean>
spring提供了很多*aware接口,比较常用的就是BeanFactoryAware,ApplicationContextAware,BeanNameAware
实现这些接口的Bean则能获得相应的BeanFactory,ApplicationContext实例,从而能直接获得容器信息。
3、FactoryBean接口作用就是封装自己定制的实例化逻辑(例如你想用工厂模式来实例化,或者Class.getInstance()),然后让spring统一管理。
http://fuhuijun.iteye.com/blog/1260609
http://readwall.blog.163.com/blog/static/10127132201042751036331
FactoryBean 用于在 spring 容器中创建其他的 Bean, 我们平时用得最多的 JndiObjectFactoryBean, hibernate 的 LocalSessionFactoryBean 都是 FactoryBean 的具体实现, 既然如此, 读取动态配置就变得易如反掌了, 假如我们要实现动态读取数据库配置的功能, 拿使用率最高的 BasicDatasource 为例, 简单的实现一个 BasicDatasource FactoryBean 如下即可
代码
public class BasicDataSourceFactoryBean implements FactoryBean {
public Object getObject() throws Exception {
BasicDataSource dataSource = new BasicDataSource();
// 读取外部配置, 设置到 dataSource 中 ...
return dataSource;
}
public Class getObjectType() {
return BasicDataSource.class;
}
public boolean isSingleton() {
return true;
}
}
然后在 spring 中如此声明
<bean id="dataSource" class="BasicDataSourceFactoryBean ">
... 你的配置来源
</bean>
4、BeanPostProcessor,BeanFactoryPostProcessor接口都是容器扩展点,容许spring在bean初始化或者销毁的时候回调,回调顺序可以用order来指定,前提是必须执行Ordered接口。