Spring,java反射特性记录

java反射机制运行时动态生成class  和    spring 的bean管理 给代码提供了极大的灵活性,简直到了为所欲为的地步,不建议乱用,这里记录一下平时用到的

一  bytecode方式(例如java assist) 动态生成class ,dubbo里里有源码,有空整理

 

二  spring容器里动态替换掉运行的类,动态增加bean的 属性。

 1. 下面的代码提供运行条件和待测试的bean

 1 @Component
 2 @Lazy(false)
 3 public class SpringUtil implements ApplicationContextAware {
 4 
 5     private static ApplicationContext applicationContext;
 6     //获取applicationContext
 7     public static ApplicationContext getApplicationContext() {
 8         return applicationContext;
 9     }
10 
11     //通过name获取 Bean.
12     public static Object getBean(String name) {
13         return getApplicationContext().getBean(name);
14     }
15 
16     //通过class获取Bean.
17     public static <T> T getBean(Class<T> clazz) {
18         return getApplicationContext().getBean(clazz);
19     }
20 
21     //通过name,以及Clazz返回指定的Bean
22     public static <T> T getBean(String name, Class<T> clazz) {
23         return getApplicationContext().getBean(name, clazz);
24     }
25 
26     @Override
27     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
28         if (SpringUtil.applicationContext == null) {
29             SpringUtil.applicationContext = applicationContext;
30         }
31     }
32 
33     private SpringUtil() {
34     }
35 }
 1 public interface BeanTestMe {
 2     String getIdentity();
 3 }
 4 
 5 @Service("beanTestMe1")
 6 public class BeanTestMe1 implements BeanTestMe{
 7     public String getIdentity(){
 8         return "1";
 9     }
10 }
11 
12 @Service("beanTestMe2")
13 public class BeanTestMe2 implements BeanTestMe{
14     public String getIdentity(){
15         return "2";
16     }
17 }

 

 

2.下面这个类具体操作bean

 1 @Component
 2 @Lazy(false)
 3 public class InitBeanPropertyConfig implements ApplicationListener<ContextRefreshedEvent> {
 4     @Override
 5     public void onApplicationEvent(ContextRefreshedEvent event){
 6         if (event.getApplicationContext().getParent() == null) {
 7         /**
 8          获取beanfactroy等类
 9         */
10             ApplicationContext ac = SpringUtil.getApplicationContext();
11             DefaultListableBeanFactory fty = (DefaultListableBeanFactory) ac.getAutowireCapableBeanFactory() ;
12 
13         /**
14          获取mybFormalClientService,增加dependsOn属性
15         */
16             BeanDefinition bd = fty.getBeanDefinition("mybFormalClientService");
17             //fty.getBeanDefinitionNames()
18             String[] dependsOn = bd.getDependsOn();
19             String[] dependsOnNew;
20             if (dependsOn == null || dependsOn.length == 0){
21                 dependsOnNew = new String[1];
22                 dependsOnNew[0] = "mwMaskConvertHelper";
23             }else{
24                 dependsOnNew = new String[dependsOn.length + 1];
25                 System.arraycopy(dependsOn,0,dependsOnNew,0,dependsOn.length);
26                 dependsOnNew[dependsOnNew.length-1] = "mwMaskConvertHelper";
27             }
28             bd.setDependsOn(dependsOnNew);
29             fty.registerBeanDefinition("mybFormalClientService", bd);
30 
31        /**
32          动态获取到beanTestMe1,把执行类换成BeanTestMe2,注册,然后再次执行结果是BeanTestMe2 的结果
33         */
34             bd = fty.getBeanDefinition("beanTestMe1");
35             ((BeanTestMe)fty.getBean("beanTestMe1")).getIdentity();
36             bd.setBeanClassName("com.ymm.crm.biz.BeanTestMe2");
37             fty.registerBeanDefinition("beanTestMe1", bd);
38             ((BeanTestMe)fty.getBean("beanTestMe1")).getIdentity();
39         }
40     }
41 }

 

三 继承spring  的 FactoryBean 动态生成bean, 服务注册Pegion 源码里使用到了。

 

posted @ 2019-09-27 16:14  thinkqin  阅读(234)  评论(0编辑  收藏  举报