一.Spring如何管理bean
1.@Resource 默認(rèn)根據(jù)name匹配,未找到再根據(jù)type匹配;
2.@Autowired 根據(jù)類型匹配;
3.無實(shí)現(xiàn)類,根據(jù)接口生成代理類,把代理類放到FactoryBean的實(shí)現(xiàn)中,最后把FactoryBean的實(shí)現(xiàn)類注冊(cè)到Spring容器中,本篇具體講第三種方式。
二.核心步驟方法
public interface ITestDao {
String test();
}
public class ProxyBeanFactory implements FactoryBean {
/**
* 返回實(shí)例對(duì)象
* @return
* @throws Exception
*/
@Override
public Object getObject() throws Exception {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class[] classes = {ITestDao.class};
InvocationHandler handler = (proxy, method, args) -> "你被代理了 " + method.getName();
return Proxy.newProxyInstance(classLoader, classes, handler);
}
/**
* 返回實(shí)例類型
* @return
*/
@Override
public Class<?> getObjectType() {
return ITestDao.class;
}
/**
* 是否單例
* @return
*/
@Override
public boolean isSingleton() {
return true;
}
}
@Component
public class RegisterBeanFactory implements BeanDefinitionRegistryPostProcessor
{
/**
* 實(shí)現(xiàn) BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法,獲取 Bean 注冊(cè)對(duì)象。
* 定義 Bean,GenericBeanDefinition,這里主要設(shè)置了我們的代理類工廠。
* 創(chuàng)建 Bean 定義處理類,BeanDefinitionHolder,這里需要的主要參數(shù);定義 Bean 和名稱 setBeanClass(ProxyBeanFactory.class)。
* 將 bean注冊(cè)到spring容器中去,registry.registerBeanDefinition()
* @param beanDefinitionRegistry
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(ProxyBeanFactory.class);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, "testDao");
System.out.println("注冊(cè) testDao" + definitionHolder);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, beanDefinitionRegistry);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
@Test
public void test() {
AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext(RegisterBeanFactory.class);
ITestDao testDao = (ITestDao) application.getBean("testDao");
String result = testDao.test();
System.out.println(result);
}
三.測(cè)試結(jié)果

image