本文共 3139 字,大约阅读时间需要 10 分钟。
spring容器中Bean的加载包含一系列的过程,bean的启动过程主要是org.springframework.context.support.AbstractApplicationContext.refresh() 方法。主要阶段包含:
// Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); }
其中这个:
// Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);
意思就是调用注册PostProcessor。进入invokeBeanFactoryPostProcessors函数。最后调用栈会执行到:
void org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)
这里将会处理这些Processor。
实现ApplicationContext接口之下的具体类的容器都是在容器初始化的时候实例化了对象,初始化的时候我们如果要对实例进行干预可以实现org.springframework.beans.factory.config.BeanFactoryPostProcessor。我们可以利用这个接口做一些事情,例如我们可以在数据库里配置密码为密文,然后使用程序需要使用的对象动态的解密数据,这样达到安全性保证。 我们定义:class User { private String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
配置初始化参数:
测试:
User user = context.getBean("user",User.class); System.out.println(user.getPassword());
打印 : 123456
如果我们干预一下User的实例化:class MyPostBeanProcessor extends SpringBase implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 修改user User user = (User) beanFactory.getBean("user",User.class); // 模拟加密算法 // 真实密码为原来的密码数字对应的+1 user.setPassword(decode(user.getPassword())); } private String decode(String password) { StringBuffer sb = new StringBuffer(); for (char c : password.toCharArray()) { sb.append((int) c - 47); } return sb.toString(); }}
测试为:
234567 完成了实例化动态修改配置的效果转载地址:http://itklj.baihongyu.com/