俗话说得好“工欲善其事必先利其器”,现如今springboot与springcloud已成为快速构建web应用的利器。作为一个Java工程师,知道如下的spring扩展点,可能会让你编写出扩展性、维护性更高的代码。

bean的生命周期

BeanFactoryPostProcessor接口

spring源码中对该类功能描述如下:
/*Factory hook that allows for custom modification of an application context's
bean definitions, adapting the bean property values of the context's underlying
bean factory.*/

翻译过来的意思大致是:工厂钩子允许自定义应用上下文中的bean定义,调整上下文bean

工厂中bean的属性值。直白点的意思就是允许修改bean定义的属性值。

通过一个简单的例子,来了解下钩子的简单应用:定义一个类GoodEntity和DemoBeanFactoryProcessor。自定义的DemoBeanFactoryProcessor功能很简单就是从BeanFactory中获取goodEntity的bean定义,然后设置了goodentity的name属性值。

@Slf4j
@Component
@Data
public class GoodEntity {private String name;}
@Component
public class DemoBeanFactoryProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition goodEntity = beanFactory.getBeanDefinition("goodEntity");goodEntity.getPropertyValues().addPropertyValue("name", "测试设置货品名称");}
}
@SpringBootApplication
public class CourseApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(CourseApplication.class, args);System.err.println(run.getBean(GoodEntity.class).getName());}
}

输出结果如下,可以到打印出了我们设置name属性值。

2021-01-15 15:33:28.818  INFO 7112 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/mall]   : Initializing Spring embedded WebApplicationContext
2021-01-15 15:33:28.818  INFO 7112 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 819 ms
2021-01-15 15:33:28.943  INFO 7112 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-01-15 15:33:29.054  INFO 7112 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '/mall'
2021-01-15 15:33:29.062  INFO 7112 --- [           main] c.i.s.s.course.CourseApplication         : Started CourseApplication in 1.409 seconds (JVM running for 2.186)
测试设置货品名称

PS:通常情况下如果对两个bean的初始化顺序有要求,我们可以通过BeanDefinition的setDependsOn,来保证两个Bean的初始顺序。

BeanDefinitionRegistryPostProcessor接口

该接口是BeanFactoryPostProcessor的扩展接口,允许在普通的BeanFactoryPostProcessor生效前,向beanfactory中注册BeanDefinition。通过一段代码我们了解下该接口的作用

@Component
public class DemoBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {String beanClassName = OrderEntity.class.getName();AbstractBeanDefinition beanDefinition =BeanDefinitionBuilder.genericBeanDefinition(beanClassName).getBeanDefinition();beanDefinition.getPropertyValues().addPropertyValue("orderId", "id-0001");String beanName = AnnotationBeanNameGenerator.INSTANCE.generateBeanName(beanDefinition, registry);registry.registerBeanDefinition(beanName, beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderEntity implements Serializable {private String orderId;private String address;private List<GoodEntity> goods;private LocalDateTime createTime;private String userId;private Integer pay;private BigDecimal cost;}
@SpringBootApplication
public class CourseApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(CourseApplication.class, args);System.err.println(run.getBean(OrderEntity.class).getOrderId());}
}

大致意思是通过DemoBeanDefinitionRegistryPostProcessor向beanfactory中注册bean定义,然后从spring容器中获取该bean,打印属性。

BeanPostProcessor接口

源码中对该类的描述
/*Factory hook that allows for custom modification of new bean instances —for example, checking for marker interfaces or wrapping beans with proxies.*/

翻译过来的大致意思是:工厂钩子允许自定义修改新的bean实例,例如检查标记的接口或者使用代理包裹bean。下面我们通过代码来看看该钩子的作用,before修改orderid,after打印。

@Component
public class DemoBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof OrderEntity) {OrderEntity entity = (OrderEntity)bean;System.err.println("before");System.err.println("orderId " + entity.getOrderId());entity.setOrderId("id-0002");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof OrderEntity) {OrderEntity entity = (OrderEntity)bean;System.err.println("after");System.err.println("orderId " + entity.getOrderId());}return bean;}
}

输出结果如下:

2021-01-15 17:41:17.783  INFO 9488 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
before
orderId id-0001
after
orderId id-0002
2021-01-15 17:41:17.904  INFO 9488 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '/mall'
2021-01-15 17:41:17.912  INFO 9488 --- [           main] c.i.s.s.course.CourseApplication         : Started 

PS:感兴趣的朋友可以看看,spring的aop生成代理对象就是依赖该钩子完成的。

Aware接口

  • BeanFactoryAware —— 获取BeanFactory对象

  • BeanClassLoaderAware —— 获取加载Bean的ClassLoader

  • BeanNameAware —— 获取beanName

  • ApplicationContextAware —— 获取ApplicationContext

  • EnvironmentAware —— 获取spring的上下文环境Environment

看看具体的示例:

@Slf4j
@Component
@Data
public class DemoAwareimplements BeanFactoryAware, BeanClassLoaderAware, BeanNameAware, ApplicationContextAware, EnvironmentAware {private ClassLoader classLoader;private BeanFactory beanFactory;private String name;private ApplicationContext applicationContext;private Environment environment;@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {this.classLoader = classLoader;log.info("classloader {}", classLoader.getClass());}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;log.info("beanFactory {}", beanFactory.getClass());}@Overridepublic void setBeanName(String name) {this.name = name;log.info("name {}", name);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;log.info("applicationContext {}", applicationContext.getClass());}@Overridepublic void setEnvironment(Environment environment) {this.environment = environment;log.info("environment {}", environment.getClass());}}

PS:这些个Aware我个人最喜欢用的是ApplicationContextAware和EnvironmentAware。可以获取Spring的上下文和Spring运行时的环境配置信息,就可以随意获取bean和环境配置信息了。

InitializingBean接口

spring中对该接口功能的描述
/* Interface to be implemented by beans that need to react once all their propertieshave been set by a {@link BeanFactory}: e.g. to perform custom initialization,or merely to check that all mandatory properties have been set*/

翻译过来的意思大致是:实现该接口的bean,会在所有的属性都被(BeanFactory)设置完成后执行。例如,实现自定义的初始化,或者检查必要的属性是否被设置了。

@Component
public class DemoInitializingBean implements InitializingBean {@Autowiredprivate OrderEntity orderEntity;private String name;@Overridepublic void afterPropertiesSet() throws Exception {if (orderEntity != null) {System.out.println("setted");}name = "already";}
}
http://www.taodudu.cc/news/show-891388.html

相关文章:

  • 分布式数据库管理系统介绍
  • 后端:Java中如何更优雅的处理空值,看完你就懂了!
  • 分布式查询处理和优化相关知识介绍
  • 分布式数据库基础:分布式事务相关概念介绍
  • 大型分布式存储方案MinIO介绍,看完你就懂了!
  • ElementUI:文本框实现远程搜索的用法
  • 分布式数据库基础:分布式数据库故障
  • 后端技术:命名不规范,lombok泪两行!
  • 后端技术:Java程序员常用的11个API,你都知道吗?
  • 后端技术:Java 泛型 T,E,K,V的含义,看完本文你就明白了?
  • 电脑技巧:C盘爆满该如何清理,实用的清理方案,小白必备
  • 后端技术:Java中Spring 和 Spring Boot 有哪些区别,看完你就明白了!
  • 17 张程序员专属壁纸,有你喜欢的吗?
  • 操作系统:电脑的回收站的秘密你知道吗?
  • 电脑维修的十大原则,你都认同吗?
  • 后端:REST API URI 设计的七准则
  • 开发工具:IDEA EasyCode插件用法(很实用)
  • 后端技术:这35 个细节,提升你的 Java 代码质量
  • 程序员能力提升:你应该知道的那些编程原则!!
  • GitHub:一份玩转 GitHub 的秘诀,值得收藏!
  • 程序人生:这5个程序员,改变了世界,你都认识吗!
  • 操作系统:Win10系统下LocalNow和Roaming文件夹介绍
  • 工具:分享IntelliJ IDEA 5条调试技巧,太实用了!
  • 网络基础:计算机网络由基础到深入常用知识集锦!
  • 后端:请谨慎使用Arrays.asList、ArrayList的subList
  • SQLServer:用户自定义数据类型用法
  • 数据库知识:SQLServer变量相关知识介绍
  • 存储知识:U盘的实际容量要比标注容量小,你知道原因吗?
  • Java:处理 Exception 的几种实践,很优雅,值得推荐!
  • 操作系统:Linux环境变量相关知识总结

后端:spring提供的钩子,你知道哪些?相关推荐

  1. spring的钩子_spring提供的钩子,你知道哪些

    俗话说得好"工欲善其事必先利其器",现如今springboot与springcloud已成为快速构建web应用的利器.作为一个爪洼工程师,知道如下的spring扩展点,可能会让你编 ...

  2. 前端Vue+ElementUI的Pagination分页组件实现分页展示 后端Spring Boot +Mybatis Plus实现分页接口

    前端Vue+ElementUI的Pagination分页组件实现分页展示 & 后端Spring Boot +Mybatis Plus实现分页接口 很久没有更新博客了,主要原因是博主一直在补充自 ...

  3. 代理后域名及Https协议向后传递,后端Spring获取不到问题记录及分析

    项目场景: 项目使用前后端分离开发,前后端都部署在k8s中. 前端 前端项目通过nginx代理到后端服务器. nginx中配置了如下Header: proxy_set_header Host $hos ...

  4. spring: 使用Spring提供的JDBC模板(使用profiles选择数据源/使用基于JDBC驱动的数据源)...

    Spring提供的JDBC框架负责管理资源和异常处理,从而可以简化开发者的JDBC代码.开发者只需要编写写入和读取数据库相关的代码即可. 正如在之前的小节中论述过的,Spring将数据库访问过程中的模 ...

  5. 给容器中注册组件 || @Scope -- @Lazy -- @Conditional({Condition}) -- @Import--使用Spring提供的 FactoryBean

    * @Scope:调整作用域    * prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中.       *              每次获取的时候才会调用方法创建对象: ...

  6. Java-利用Spring提供的Resource/ResourceLoader接口操作资源文件

    背景 资源访问接口 主要方法 主要实现类 例子 WritableResource ClassPathResource ServletContextResource 对资源文件编码 资源加载 资源地址表 ...

  7. 【Spring学习】spring提供的三种定时任务

    在spring中我们有三种不同的定时任务:基于Quartz的定时机制.基于Timer的定时机制.基于Executor的定时机制. 1.基于Quartz的定时任务机制 下面详细解释这个类图中涉及的关键类 ...

  8. Spring提供获取应用上下文的工具

    Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一 ...

  9. (转)Spring提供的CharacterEncoding和OpenSessionInView功能

    http://blog.csdn.net/yerenyuan_pku/article/details/52902282 前面我们以一种更加优雅的方式集成了Spring4.2.5+Hibernate4. ...

最新文章

  1. [nowCoder] 局部最小值位置
  2. 2010年上半年计算机专业技术资格考试工作安排
  3. 当进度对话框和后台线程处于活动状态时,如何处理屏幕方向变化?
  4. 记一次找因 Redis 使用不当导致应用卡死 bug 的过程
  5. MyClass a,b[2],*p[2]调用了几次构造函数
  6. android动画view上移,在Android开发中使用View制作一个引导动画
  7. mysql 如果存在修改_mysql如存在并发修改可能,一定要注意保证数据一致性
  8. HDU2500 做一个正气的杭电人【水题】
  9. springmvc07 Json处理
  10. TeamViewer 远程连接一直显示正在初始化显示参数的解决方案
  11. Unity3D流体插件FluidSim使用总结
  12. “郭德纲”挤兑死人不带脏字,经典…
  13. cocos2d-js飞机项目:飞机爆炸效果
  14. 非线性规划:实例与matlab应用
  15. php禁用session和cookies,session与cookie的区别是什么?如果客户端禁用了cookie功能,将会对session有什么影响?...
  16. 【Android】世界各国语言代码
  17. 世界读书日:作为一个优秀的程序员请收藏这份书单
  18. 64位Win10 2004正式版镜像下载
  19. __attribute_((naked))
  20. Substance Painter入门

热门文章

  1. 实现 IE6 支持 position fixed 的 CSS 属性
  2. Tree.Panel各项属性
  3. highgui基础 OpenCV trackbar
  4. 华为服务器故障灯不开机_华为服务器日常维护及故障处理介绍V.ppt
  5. 使用Nginx+WordPress搭建个人网站
  6. 数组各元素出现的次数
  7. 1. 观察者模式总结(C++)
  8. java的类属性默认有this 但容易与参数重名 所以需要显性的加上this 以分区别
  9. LeetCode String Compression
  10. input输入框修改后自动跳到最后一个字符