Spring(boot)扩展点整理

1、BeanFactoryPostProcessor(BeanDefinitionRegistryPostProcessor)可以修改一个类的上下文

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UseRule.class);
        beanDefinitionBuilder.addPropertyValue("age", 66);
        beanDefinitionBuilder.addPropertyValue("sex", "unkonw");
        beanDefinitionRegistry.registerBeanDefinition("beanName",beanDefinitionBuilder.getBeanDefinition());
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UseRule.class);
        beanDefinitionBuilder.addPropertyValue("age", 66);
        beanDefinitionBuilder.addPropertyValue("sex", "unkonw");
        defaultListableBeanFactory.registerBeanDefinition("beanName", beanDefinitionBuilder.getBeanDefinition());
    }
}

2、 @Import(ImportBeanDefinitionRegistrar,ImportSelector)

1)ImportSelector:
最常见到的就是Springboot启动时,利用ImportSelector找到META-INF\spring.factories配置文件下配置的类,将其扫描到字符串数组中,然后哦在Spring容器reflush时注册为bean。
Spring(boot)扩展点整理_第1张图片
Spring(boot)扩展点整理_第2张图片
在这里插入图片描述
也可以自己实现ImportSelector接口,重写selectImports方法,将需要注册的bean全类名通过该方法以数组方式返回,再在一个配置类中通过@Import注解导入自己的实现类即可。
2)实现ImportBeanDefinitionRegistrar
Spring(boot)扩展点整理_第3张图片
3)@Import还可以导入普通类,直接将一个类注册为bean

3、Aware(ApplicationContextAware,BeanFactoryAware)

1)BeanFactoryAware可以通过bean工程的回调方法拿到bean工厂

@Component
public class MyBeanFactory implements BeanFactoryAware {

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }


    public Object getBean (String beanName) {
        return beanFactory.getBean(beanName);
    }
}

2)ApplicationContextAware与上面类似,实现这个接口可以拿到spring上下文对象,同样可以获取bean对象

@Component
public class MyBeanFactory implements ApplicationContextAware {

    private ApplicationContext beanFactory;



    public Object getBean (String beanName) {
        return beanFactory.getBean(beanName);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.beanFactory = applicationContext;
    }
}

4、InitializingBean || @PostConstruct

实现InitializingBean的afterPropertiesSet方法,在bean初始化时会调用该方法。
在方法上加上@PostConstruct注解同样是在bean初始化时会调用该方法。

5、FactoryBean

前面扩展点中有通过修改bd的方式修改一个bean,或者自己构建一个bd来注册一个bean,这种方式比较繁琐,可以通过实现FactoryBean的getObject方法,通过new的方式创建一个对象,这个对象会被spring管理,作为一个bean。

6、SmartInitializingSingleton

在spring容器管理的所有单例对象(非懒加载对象)初始化完成之后调用的回调接口。其触发时机为 postProcessAfterInitialization 之后。
使用场景:用户可以扩展此接口在对所有单例对象初始化完毕后,做一些后置的业务处理。

扩展方式为:

public class TestSmartInitializingSingleton implements SmartInitializingSingleton {  
    @Override  
    public void afterSingletonsInstantiated() {  
        System.out.println("业务处理");  
    }  
}

7、ApplicationListener

最常见到的就是Springboot启动时,通过事件监听机制完成的启动初始化。
Spring(boot)扩展点整理_第4张图片
自定义一个简单的示例:

@Component
public class MyApplicationListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent applicationEvent) {
        String pm1 = applicationEvent.getPm1();
    }
}

@Data
public class MyEvent extends ApplicationEvent {

    private String pm1;

    public MyEvent(Object source,String pm1) {
        super(source);
        this.pm1 = pm1;
    }
}
@Service
public class TestService {

    @Autowired
    private WebApplicationContext context;

    public void test () {
        MyEvent event = new MyEvent("object","pm1");
        context.publishEvent(event);
    }

}

这样在执行test方法时,自定义的事件就会被触发。

8、HandlerInterceptor

实现HandlerInterceptor接口的下面三个方法:
preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。
afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception;

void postHandle(
		HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
		throws Exception;

void afterCompletion(
		HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
		throws Exception;

9、CommandLineRunner||ApplicationRunner

在springBoot项目启动的最后,会执行所有的CommandLineRunner和ApplicationRunner,有时候可以用来提前加载一些热点缓存数据。
Spring(boot)扩展点整理_第5张图片
只需要实现上面的接口,重新run方法即可,如果有多个Runner可以通过@Order注解定义执行顺序。

10、BeanPostProcessor

该接口目前有两个方法:
postProcessBeforeInitialization 该在初始化方法之前调用。
postProcessAfterInitialization 该方法再初始化方法之后调用。

常用的扩展点总结了以上十点,其他的扩展点如果有常见的应用场景再补充。

你可能感兴趣的:(基础框架,spring,java,spring,boot)