Skip to main content

Spring Boot

Singleton Inject but need dynamic changing value

A bug finds in those of tasks where you need change the date by the nature.
Firstly You should inject a prototype bean to spring context, instead of injecting a singleton object; Secondly you need use this way.

@Component
public class SingletonService {

// Use ObjectFactory (can also use javax.inject.Provider or Spring's Provider)
@Resource
private ObjectFactory<PrototypeBean> prototypeBeanFactory;

public void callTest() {
PrototypeBean prototypeBean = prototypeBeanFactory.getObject();
prototypeBean.doSomething();
}
}

Startup Problems

Springboot startup error org.springframework.boot does not exist

Suggest using method 2 to input mvn idea:idea in terminal, method 1 in Spring Boot project, when running other Main method test classes, will restart SpringBoot project, if you still get from ApplicationContext, then you will receive error container already closed. See blog

spring boot source code running SpringApplication error

Could not find artifact lifecycle-mapping:lifecycle-mapping:jar:sources:1.0.0 See blog Already paid to view! Speechless

gradle spring boot 3.0 import error

Invalid source release: 17

Ensure gradle version JDK 17 and JDK version are correct.

image-20230728021351697

Startup console log has no color

Introduce in spring-logback.xml

<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="TRACE"/>

logback modify log print content

Code: extends ThrowableHandlingConverter impl convert method

logback config

<conversionRule convertionWord="someKeyMsg" convertClass="com.xxx.xxx.Xclass"/>

Packaging Problems

after run the packaged jar occurs this unable to find main class

Method 1. Replace plugin

<!--<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>none</mainClass>
<classifier>execute</classifier>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>

Method 2: Remove spring-boot parent, then use spring boot plugin to package


Get Real Class Annotation of AOP Proxy Object

In Spring Boot, after using AOP technologies like @Aspect, injected Bean is proxy object. Directly through getClass().getAnnotation() often cannot get annotation on original class (especially JDK dynamic proxy).

Core Solution: Use Spring provided AopProxyUtils to penetrate proxy, get final original business class.

Click to view
import org.springframework.aop.framework.AopProxyUtils;
// ...
@Component
public class MyAnnotationScanner implements ApplicationRunner {

private final ApplicationContext context;
private final Map<String, MyAnnotation> cacheMap = new ConcurrentHashMap<>();

public MyAnnotationScanner(ApplicationContext context) {
this.context = context;
}

@Override
public void run(ApplicationArguments args) {
// 1. Get all Beans with specific annotation
Map<String, Object> beans = context.getBeansWithAnnotation(MyAnnotation.class);

beans.forEach((name, bean) -> {
// 2. Penetrate proxy, get real class (TargetClass)
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);

// 3. Extract annotation information
MyAnnotation anno = AnnotationUtils.findAnnotation(targetClass, MyAnnotation.class);

if (anno != null) {
cacheMap.put(targetClass.getName(), anno);
}
});
}
}
Agreement
The code part of this work is licensed under Apache License 2.0 . You may freely modify and redistribute the code, and use it for commercial purposes, provided that you comply with the license. However, you are required to:
  • Attribution: Retain the original author's signature and code source information in the original and derivative code.
  • Preserve License: Retain the Apache 2.0 license file in the original and derivative code.
The documentation part of this work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . You may freely share, including copying and distributing this work in any medium or format, and freely adapt, remix, transform, and build upon the material. However, you are required to:
  • Attribution: Give appropriate credit, provide a link to the license, and indicate if changes were made.
  • NonCommercial: You may not use the material for commercial purposes. For commercial use, please contact the author.
  • ShareAlike: If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.