Spring让人眼前一亮的11个小技巧( 四 )

在postProcessBeanFactory方法中,可以获取BeanDefinition的相关对象,并且修改该对象的属性 。
8.初始化Bean前后有时,你想在初始化Bean前后,实现一些自己的逻辑 。
这时可以实现:BeanPostProcessor接口 。
该接口目前有两个方法:

  • postProcessBeforeInitialization 该在初始化方法之前调用 。
  • postProcessAfterInitialization 该方法再初始化方法之后调用 。
例如:
@Componentpublic class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof User) {((User) bean).setUserName("苏三说技术");}return bean;}}如果spring中存在User对象,则将它的userName设置成:苏三说技术 。
其实,我们经常使用的注解,比如:@Autowired、@Value、@Resource、@PostConstruct等,是通过AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor实现的 。
9.初始化方法【Spring让人眼前一亮的11个小技巧】目前spring中使用比较多的初始化bean的方法有:
  1. 使用@PostConstruct注解
  2. 实现InitializingBean接口
9.1 使用@PostConstruct注解@Servicepublic class AService {@PostConstructpublic void init() {System.out.println("===初始化===");}}在需要初始化的方法上增加@PostConstruct注解,这样就有初始化的能力 。
9.2 实现InitializingBean接口@Servicepublic class BService implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("===初始化===");}}实现InitializingBean接口,重写afterPropertiesSet方法,该方法中可以完成初始化功能 。
10.关闭容器前有时候,我们需要在关闭spring容器前,做一些额外的工作,比如:关闭资源文件等 。
这时可以实现DisposableBean接口,并且重写它的destroy方法:
@Servicepublic class DService implements InitializingBean, DisposableBean {@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean destroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean afterPropertiesSet");}}这样spring容器销毁前,会调用该destroy方法,做一些额外的工作 。
通常情况下,我们会同时实现InitializingBean和DisposableBean接口,重写初始化方法和销毁方法 。
11.自定义作用域我们都知道spring默认支持的Scope只有两种:
  • singleton 单例,每次从spring容器中获取到的bean都是同一个对象 。
  • prototype 多例,每次从spring容器中获取到的bean都是不同的对象 。
spring web又对Scope进行了扩展,增加了:
  • RequestScope 同一次请求从spring容器中获取到的bean都是同一个对象 。
  • SessionScope 同一个会话从spring容器中获取到的bean都是同一个对象 。
即便如此,有些场景还是无法满足我们的要求 。
比如,我们想在同一个线程中从spring容器获取到的bean都是同一个对象,该怎么办?
这就需要自定义Scope了 。
第一步实现Scope接口:
public class ThreadLocalScope implements Scope {private static final ThreadLocal THREAD_LOCAL_SCOPE = new ThreadLocal();@Overridepublic Object get(String name, ObjectFactory<?> objectFactory) {Object value = https://www.huyubaike.com/biancheng/THREAD_LOCAL_SCOPE.get();if (value != null) {return value;}Object object = objectFactory.getObject();THREAD_LOCAL_SCOPE.set(object);return object;}@Overridepublic Object remove(String name) {THREAD_LOCAL_SCOPE.remove();return null;}@Overridepublic void registerDestructionCallback(String name, Runnable callback) {}@Overridepublic Object resolveContextualObject(String key) {return null;}@Overridepublic String getConversationId() {return null;}}

经验总结扩展阅读