环境:SpringBoot2.7.16
1. Bean初始化及销毁
如你希望Bean对象被创建过程中执行以下初始化动作,你可以通过实现InitializingBean接口或者使用@PostConstruct注解。
@Component public class InitDataToRedis implements InitializingBean { public void afterPropertiesSet() throws Exception { // 初始化 } } @Component public class PersonService { @PostConstruct public void init() { // 初始化 } }
如希望在容器关闭时执行资源释放或者其它一些动作可以实现DisposableBean接口或者使用@PreDestroy注解。
public class Person implements DisposableBean { public void destroy() { // 销毁动作 } } @Component public class PersonService { @PreDestroy public void destroy() { // 销毁 } }
2. 单例Bean注入多例Bean
// 多例Bean @Component @Scope("prototype") public class PersonService { } // 默认单例Bean @Controller public class PersonController {}
如上如何在PersonController中注入PersonService呢?通过如下方法
方法1:
@Lazy private PersonService personService ;
方法2:
@Component @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) public class PersonService {}
方法3:
public class PersonController { @Resource private ApplicationContext context ; public Object index() { PersonService ps = this.context.getBean(PersonService.class) ; } }
3. BeanPostProcessor接口
如需要Bean在初始化前后执行相关的动作,可以通过实现该接口。
public class PackBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // 初始化前执行 } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // 初始化后执行 } }
4. BeanFactoryPostProcessor接口
如你希望在创建Bean对象之前修改BeanDefinition的相关属性可以通过实现该接口
public PackBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition definition = beanFactory.getBeanDefinition("person") ; // 修改了作用域 definition.setScope("prototype") ; } }
5. 动态注册Bean
如需要根据添加动态注册Bean,比如通过扫描包下的类符合条件的类注册为Bean对象,则可以通过如下的方式。
public class RepositoryBeanDefinitionRegister implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { // 动态注册person registry.registerBeanDefinition("person", BeanDefinitionBuilder.genericBeanDefinition(Person.class).getBeanDefinition()); } }
6.导入配置类
详细查看《想成为Spring专家?了解@Import注解的三种用法是必备的!》
7. *Runner接口
如需要在应用程序成功启动以后,执行一些任务,可以通过实现ApplicationRunner或者CommandLineRunner接口。
public class App implements CommandLineRunner { public void run(String... args) throws Exception { // 执行任务 } } // 或 public class App implements ApplicationRunner { public void run(ApplicationArguments args) throws Exception { // 执行任务 } }
8. 全局异常处理
当应用发生异常时可以通过注册全局异常处理,统一处理异常信息
@RestControllerAdvice public class GlobalControllerAdvice { @ExceptionHandler({Exception.class}) public Object handle(Exception e) { // 其它处理 return R.failure(R.ResultCode.FAILURE, e.getMessage()) ; } }
10 全局类型转换
自定义类型转换
public class CustomGenericConverter implements GenericConverter { @Override public Set<ConvertiblePair> getConvertibleTypes() { ConvertiblePair teacherPair = new ConvertiblePair(String.class, Teacher.class) ; ConvertiblePair studentPair = new ConvertiblePair(String.class, Student.class) ; Set<ConvertiblePair> pairs = new HashSet<>() ; pairs.add(teacherPair) ; pairs.add(studentPair) ; return pairs ; } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { String str = null ; if (sourceType.getObjectType() == String.class) { str = (String) source ; } if (targetType.getObjectType() == Teacher.class) { String[] t = str.split("\\|") ; return new Teacher(t[0], Integer.valueOf(t[1])) ; } if (targetType.getObjectType() == Student.class) { String[] t = str.split("\\|") ; return new Student(t[0], t[1]) ; } return null ; } }
注册类型转换器
@Component public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new CustomGenericConverter()) ; } }
以上示例注册了一个,将字符串转换为Teacher和Student。
11. 获取BeanFactory对象
如果你希望在Bean中获取BeanFactory,可以通过实现BeanFactoryAware接口
@Service public class PersonService implements BeanFactoryAware { private BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } }
相关的*Aware接口,还有很多,如:ApplicationContextAware,ServletContextAware,BeanNameAware,EnvironmentAware等。
12. Web拦截器
如你需要对某些接口进行鉴权或者其它一些处理,你可以注册自定义拦截器
@Component public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptor() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle method invoke...") ; return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle method invoke...") ; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion method invoke...") ; } }).addPathPatterns("/**") ; } } }
13. 默认AOP切面实现
BeanNameAutoProxyCreator
@Bean public BeanNameAutoProxyCreator beanNameAutoProxyCreator() { BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator(); beanNameAutoProxyCreator.setBeanNames("*Service") ; beanNameAutoProxyCreator.setInterceptorNames("tokenInterceptor"); return beanNameAutoProxyCreator ; }
上面的BeanNameAutoProxyCreator 是处理器类,只要beanName的后缀是Service结尾的都会被创建代理,然后通过以tokenInterceptor为beanName的拦截器增强。
以上是在SpringBoot项目开发中常用的一些技巧,希望本文对你有帮助。
完毕!!!
原文地址:https://mp.weixin.qq.com/s/Yd_rflO0ko1sTV4nWL9V_A