테스트 내용: Application 실행 시 custom Annotation이 붙은 메소드만 호출하는 방법
springboot version : 2.3.12.RELEASE
spring-framework version: 5.2.15.RELEASE
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>security</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
@Component
public class First {
private void invoker() {
System.out.println("First class invoker method call");
}
}
@Component
public class Second {
@MyAnnotation
private void invoker() {
System.out.println("second class invoker method call");
}
}
@Component
public class Third {
@MyAnnotation
private void invoker() {
System.out.println("Third class invoker method call");
}
}
//호출될 클래스 및 메소드
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//annotation 정의
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.core.SpringVersion;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@Component
public class AppRunner implements ApplicationRunner {
// @Autowired
//private AnnotationConfigApplicationContext context; //일반 application 인 경우
@Autowired
private AnnotationConfigServletWebServerApplicationContext context; //web application 인 경우
//private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void run(ApplicationArguments args) {
System.out.println(
SpringVersion.getVersion());
System.out.println(SpringBootVersion.getVersion());
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
Object bean = context.getBean(beanDefinitionName);
Method[] declaredMethods = bean.getClass().getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
Annotation[] annotations = declaredMethod.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof MyAnnotation) {
System.out.println("beanName: " + beanDefinitionName);
declaredMethod.setAccessible(true);
try {
System.out.println(declaredMethod.getName());
System.out.println("class name: " + bean.getClass().getName());
declaredMethod.invoke(bean);
} catch (IllegalAccessException e) {
System.out.println("can not access method " + declaredMethod.getName());
System.out.println(e.getMessage());
} catch (InvocationTargetException e) {
System.out.println(e.getMessage());
}
}
}
}
}
}
}
//application 구동 후 run 메소드 실행
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(App.class);
app.setWebApplicationType(WebApplicationType.SERVLET);
app.run(args);
}
}
//메인 메소드
@MyAnnotation가 붙은 Second, Third Class의 invoker 메소드만 호출됨을 확인