@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());
}
}
1)ImportSelector:
最常见到的就是Springboot启动时,利用ImportSelector找到META-INF\spring.factories配置文件下配置的类,将其扫描到字符串数组中,然后哦在Spring容器reflush时注册为bean。
也可以自己实现ImportSelector接口,重写selectImports方法,将需要注册的bean全类名通过该方法以数组方式返回,再在一个配置类中通过@Import注解导入自己的实现类即可。
2)实现ImportBeanDefinitionRegistrar
3)@Import还可以导入普通类,直接将一个类注册为bean
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;
}
}
实现InitializingBean的afterPropertiesSet方法,在bean初始化时会调用该方法。
在方法上加上@PostConstruct注解同样是在bean初始化时会调用该方法。
前面扩展点中有通过修改bd的方式修改一个bean,或者自己构建一个bd来注册一个bean,这种方式比较繁琐,可以通过实现FactoryBean的getObject方法,通过new的方式创建一个对象,这个对象会被spring管理,作为一个bean。
在spring容器管理的所有单例对象(非懒加载对象)初始化完成之后调用的回调接口。其触发时机为 postProcessAfterInitialization 之后。
使用场景:用户可以扩展此接口在对所有单例对象初始化完毕后,做一些后置的业务处理。
扩展方式为:
public class TestSmartInitializingSingleton implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("业务处理");
}
}
最常见到的就是Springboot启动时,通过事件监听机制完成的启动初始化。
自定义一个简单的示例:
@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方法时,自定义的事件就会被触发。
实现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;
在springBoot项目启动的最后,会执行所有的CommandLineRunner和ApplicationRunner,有时候可以用来提前加载一些热点缓存数据。
只需要实现上面的接口,重新run方法即可,如果有多个Runner可以通过@Order注解定义执行顺序。
该接口目前有两个方法:
postProcessBeforeInitialization 该在初始化方法之前调用。
postProcessAfterInitialization 该方法再初始化方法之后调用。
常用的扩展点总结了以上十点,其他的扩展点如果有常见的应用场景再补充。