테스트 내용: 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 메소드만 호출됨을 확인

+ Recent posts