ApplicationInitlizer接口与Spring工具类

写点笔记

共 4813字,需浏览 10分钟

 · 2021-07-22

项目中要灵活使用static来标记一些常用得类,static得作用就是跨对象得存在性。只要类没有被卸载掉,那么static修饰得属性就一直在。因此我们可以用static来标记一些引用,因为static一直存在,那么我们通过static得修饰就可以获得其引用得地址,不论被应用得对象身处何方。
       有了上述思想,我们就能想到在spring框架中,上下文是我们重点关切得对象。因此我们想着通过static来引用spring上下文,然后形成一个工具类。我们在项目得业务部分能够通过该工具类来操作我们得spring上下文。这块我们说一下spring扩展接口ApplicationContextInitializer,这个接口会在spring上下文刷新之前进行调用,相当于提前将容器进行对外得暴露,当然页提供了我们修改其属性得权力。ApplicationContextInitializer得执行在prepareContext中,这块之前也大概得说过了。
我们通过查看源码,发现这块传入得是ConfigurableApplicationContext,注意这块返回得是空,意思是我们可以对这里得context进行应用标记。
protected void applyInitializers(ConfigurableApplicationContext context) {        Iterator var2 = this.getInitializers().iterator();        while(var2.hasNext()) {            ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();            Class requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);            Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");            initializer.initialize(context);        }}
通过以上得分析,我们就想这在initialize方法中将我们得上下文缓存进来。让我们来做个实践吧。
public class MyBean {
    private String name;
private String config;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getConfig() { return config; }

public void setConfig(String config) { this.config = config; }
@Override public String toString() { return "MyBean{" + "name='" + name + '\'' + ", config='" + config + '\'' + '}'; }}
静态Spring工具类
public class MySpringContentUtils {

public static ConfigurableApplicationContext context;

public static ConfigurableApplicationContext getContext() { return context; }

public static void setContext(ConfigurableApplicationContext context) { MySpringContentUtils.context = context; }

public static void registerBean(String name, Class factoryClazz, Class beanClazz, MutablePropertyValues mpv) throws BeanDefinitionStoreException { BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClazz); GenericBeanDefinition beanDefinition = (GenericBeanDefinition)beanDefinitionBuilder.getRawBeanDefinition(); beanDefinition.setBeanClass(factoryClazz == null ? beanClazz : factoryClazz); beanDefinition.setPropertyValues(mpv); BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry)context.getBeanFactory(); beanFactory.registerBeanDefinition(name, beanDefinition); }

public staticT getBean(String name) throws BeansException { return (T) context.getBean(name); }}
自定义initlizer接口
public class MyTianApplicationInitlize implements ApplicationContextInitializer {    @Override    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {        System.out.println("我来了...宝");        MySpringContentUtils.setContext(configurableApplicationContext);    }}
测试类
    public static void main(String[] args) throws InterruptedException {        SpringApplication builder=new SpringApplicationBuilder(Demo1Application.class).initializers(new MyTianApplicationInitlize()).build();        builder.run( args);        System.out.println(env.toString());        MutablePropertyValues mpv = new MutablePropertyValues();        mpv.addPropertyValue("name","tianjingle_initlizer");        MySpringContentUtils.registerBean("lisi",null, MyBean.class,mpv);        MyBean myBean= (MyBean) MySpringContentUtils.getContext().getBean("lisi");        System.out.println(myBean.toString());    }
效果
通过上述实践,我们实现了我们得目标。当然我们也可以采用spring.factories文件得方式进行添加initlizer工具。这种方式在springBoot中得starter中用得比较多,看这里。
响应得修改我们得启动类
    public static void main(String[] args) throws InterruptedException {//        SpringApplication builder=new SpringApplicationBuilder(Demo1Application.class).initializers(new MyTianApplicationInitlize()).build();//        builder.run( args);        SpringApplication.run(Demo1Application.class,args);        System.out.println(env.toString());        MutablePropertyValues mpv = new MutablePropertyValues();        mpv.addPropertyValue("name","tianjingle_initlizer");        MySpringContentUtils.registerBean("lisi",null, MyBean.class,mpv);        MyBean myBean= (MyBean) MySpringContentUtils.getContext().getBean("lisi");        System.out.println(myBean.toString());    }
至于spring.factories文件得读取,这个在启动得时候springBoot就会加载。就说这么多吧。


首页图片来自:周冬雨-Sogou百科

https://baike.sogou.com/v39745781.htm



浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报