【@PostConstruct、内部类、beancopier】

文章讨论了@PostConstruct在JDK11中的弃用,推荐使用Spring的InitializingBean和DisposableBean接口。还涉及内部类如何处理外部参数,确保数据一致性。另外,提到了Lombok在对象复制中的限制,MyBatis的XML配置注意事项,以及Hutool库的别名功能和遇到的序列化问题。文章还提及了容器技术,如Tomcat集群的优化,包括Nginx负载均衡和JVM配置。

1.@PostConstruct

1.@PostConstruct在jdk11弃用,可采用Spring的InitializingBean和DisposableBean来替代对应的功能。

2.内部类

2.内部类并不是直接调用外部传递的参数,而是利用自身的构造器对传入的参数进行备份,自己内部的方法实际调用的是自己的属性而非外部参数。
因为是对外部参数的拷贝,所以当对外部参数做出修改时,内部类中属性不会同步修改,而在代码中看来内部类是直接引用的外部变量;为了避免这样的数据不一致性,被内部类方法调用的外部参数被强制加上final修饰,保证内外参数一致性;

3.复制对象-lombok无法赋值

beancopier使用getter,第二个字母大写时 使用lombok会把第一个字母大写,第二个字母转小写,没有无法复制该字段;:使用idea生成getter;

4.mybatis

xml中’${appid}’ 如果没有引号,则sql中也不会添加’ ';

5.hutool

@Alias使用别名,多种场景下可用;

Type definition error

使用hutool json工具时,对象属性为null会被cn.hutool.json.JSONNull代替,springmvc使用@RestBody响应时无法序列化此属性,将抛出以下异常;简单解决办法为手动置该属性为null;
Type definition error: [simple type, class cn.hutool.json.JSONNull]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class cn.hutool.json.JSONNull and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.iflytek.auto.usp.common.WebApiResult[“data”])

例如:json转化对象时,json为下划线转java对象驼峰式;

6.容器

容器实际是一种进程隔离技术,通过linux的namespace技术做环境(文件系统Mount、网络Network、进程间通信IPC、主机名UTS、PID进程、用户User)隔离;通过Linux提供的cgroups机制进行硬件资源的限制;
搭建Tomcat集群,通过Nginx代理Tomcat服务器做负载均衡,对每个Tomcat的调优,合理设置设置Tomcat的最大连接数,因为Tomcat的默认最大并发数为200。适当的加大Tomcat的内存和最多线程数,设置JVM的处置大小为服务器可用内存的最大值的80%。

7.

在使用 `@PostConstruct` 方法时,如果发现通过 `@ConfigurationProperties` 注解注入的参数类为空,这通常与 Spring 的 Bean 生命周期以及依赖注入的顺序有关。`@PostConstruct` 是在 Bean 的构造函数执行之后、Bean 的初始化阶段被调用的方法,但此时是否已经完成 `@ConfigurationProperties` 的注入取决于 Spring 容器对 Bean 的处理顺序。 ### 问题原因 1. **Spring Bean 生命周期顺序** 在 Spring 容器中,Bean 的生命周期包含多个阶段,包括实例化(构造函数调用)、属性注入(如 `@Autowired`)、初始化(如 `@PostConstruct` 和 `InitializingBean` 接口的 `afterPropertiesSet` 方法)等。`@PostConstruct` 通常在 Bean 的属性注入完成后执行,因此理论上应该可以访问通过 `@ConfigurationProperties` 注入的配置类。然而,在某些特定场景下(如多 Bean 依赖关系复杂或 Bean 的作用域不同),`@PostConstruct` 方法可能在配置类尚未注入完成时就被调用,从而导致配置类为空。 2. **`@ConfigurationProperties` 与 `@Component` 的结合使用** 当使用 `@ConfigurationProperties` 注解配合 `@Component` 注解将属性类作为组件托管到 Spring 容器中时,需要确保该 Bean 已经被正确加载并注入到调用 `@PostConstruct` 的类中。如果没有正确注入,`@PostConstruct` 方法执行时,该配置类可能仍为 `null`。 3. **静态变量赋值问题** 如果在 `@PostConstruct` 方法中将配置类的属性赋值给静态变量,而该配置类本身未被正确注入,那么静态变量也会为空。这会导致在应用程序的其他部分访问这些静态变量时出现 `NullPointerException`。 ### 解决方案 1. **确保 `@ConfigurationProperties` 类被正确注入** 确保通过 `@Autowire` 或构造函数注入的方式将 `@ConfigurationProperties` 注解的类注入到需要使用的类中。例如: ```java @Component @ConfigurationProperties(prefix = "my.config") public class MyConfig { private String property; // Getter and Setter } @Component public class MyService { @Autowired private MyConfig myConfig; @PostConstruct public void init() { System.out.println(myConfig.getProperty()); // 应该不为空 } } ``` 2. **使用 `@Lazy` 延迟加载** 如果某些 Bean 的依赖关系较为复杂,可以尝试在需要注入 `@ConfigurationProperties` 类的 Bean 上添加 `@Lazy` 注解,以延迟加载该 Bean,确保在 `@PostConstruct` 方法执行时,所有依赖的 Bean 已经被正确注入。 3. **检查 Bean 的作用域** 确保 `@ConfigurationProperties` 注解的类和调用 `@PostConstruct` 方法的类处于相同的作用域(如 `singleton`)。如果它们处于不同的作用域(如 `prototype`),可能会导致依赖注入失败。 4. **使用 `InitializingBean` 接口的 `afterPropertiesSet` 方法** 如果 `@PostConstruct` 方法仍然无法正确访问 `@ConfigurationProperties` 注入的类,可以尝试使用 `InitializingBean` 接口的 `afterPropertiesSet` 方法代替 `@PostConstruct`。`afterPropertiesSet` 方法会在所有属性注入完成后调用,确保此时 `@ConfigurationProperties` 注入的类已经被正确注入。 ```java @Component public class MyService implements InitializingBean { @Autowired private MyConfig myConfig; @Override public void afterPropertiesSet() { System.out.println(myConfig.getProperty()); // 应该不为空 } } ``` 5. **确保配置类已正确加载** 检查配置类是否被正确加载到 Spring 容器中,可以通过在配置类上添加 `@Component` 或 `@Configuration` 注解,或者在主应用类上使用 `@Import` 导入该配置类。 ### 示例代码 以下是一个完整的示例,展示如何正确使用 `@ConfigurationProperties` 和 `@PostConstruct`: ```java @Component @ConfigurationProperties(prefix = "my.config") public class MyConfig { private String property; public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } } @Component public class MyService { @Autowired private MyConfig myConfig; @PostConstruct public void init() { System.out.println("Property value: " + myConfig.getProperty()); } } ``` 在 `application.yml` 文件中配置如下: ```yaml my: config: property: Hello World ``` ### 总结 `@PostConstruct` 方法执行时 `@ConfigurationProperties` 注入的参数类为空,通常是因为依赖注入尚未完成或 Bean 的加载顺序不当。通过确保正确注入、检查作用域、使用 `InitializingBean` 接口或 `@Lazy` 注解等方式,可以有效解决该问题。此外,确保配置类已正确加载到 Spring 容器中也是关键步骤之一。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值