1. AOP(Aspect Orient Programing)

 

   - 객체 지향 소프트웨어 개발에서 횡단 관심사 또는 크로스커팅 관심사(cross-cutting concerns)는 다른 관심사에 영향을 미치는 프로그램의 애스펙트이다.

   - 요구 사항에 대해 핵심 관심사항과 횡단 관심사항으로 분할, 개발, 통합하여 모듈화를 극대화하는 프로그램 기법

  

=> 결국, 횡단 관심 요소들의 처리를 모듈화를 통한 효율적으로 극복

 


2. AOP의 구성요소

    - 핵심 관심 : 시스템의 핵심 가치와 목적이 드러난 관심 영역

    - 횡단 관심 : 쉽게 분리된 모듈로 작성하기 힘든 요구 사항, 공통 모듈 

    - Joint Point : 합류 지점, 메소드 실행시점 

    - Pointcut : 어디에 적용할 것인가, 계좌이체, 입출금, 이자 계산 적용대상  

    - Aspect : 모듈 

    - Advice : 해야할일 


3.  AOP 해보기(Spring Boot 사용)

   - 패키지 목록 

 

   3-1. pom.xml에 aop 요소

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

 

 3-2. Aop 적용할 커스텀 어노테이션 생성(AopAnnotation.java)

import java.lang.annotation.*;

/**
 * 커스텀 어노테이션<br/>
 * Documented : javadoc으로 문서 생성 시 현재 어노테이션 설명 추가 <br/>
 * Retention : 어노테이션을 유지하는 정책 설정<br/>
 * Target : 어노테이션 적용 위치
 */
@Documented
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface AopAnnotation {
}

 

3-3. 테스트할 서비스(클래스) 작성(AopService.java)

import org.springframework.stereotype.Service;

@Service
public class AopService {

    @AopAnnotation
    public void print(){
        System.out.println("Aop Service print문 실행");
    }

    @AopAnnotation
    public int returnIntValue(){
        System.out.println("returnIntValue 에서 값 10 return 합니다");
        return 10;
    }
}

 

3-4. AOP 클래스 생성(AopClass.java)

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class AopClass {

    @Around("@annotation(AopAnnotation)")
    public Object aopTest(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("AopClass aopTest @Around @annotation(AopAnnotation) 동작");
        Object resultValue = proceedingJoinPoint.proceed();
        System.out.println("resultValue = > " + resultValue);
        return resultValue;
    }

    @Around("@annotation(AopAnnotation)")
    public Object aopTest2(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("AopClass aopTest2 @Around @annotation(AopAnnotation) 동작");
        Object resultValue = proceedingJoinPoint.proceed();
        return resultValue;
    }
}

 

3-5. AppRunner 작성 (AppRunner.java)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    AopService aopService;


    @Override
    public void run(ApplicationArguments args) throws Exception {
        aopService.print();
        aopService.returnIntValue();
    }
}

4. 결과화면 

블로그 이미지

미나미나미

,

 

1. 메인의 SchoolMember.name을 바꾸기

/**
 * Hello world!
 *
 */
public class App {
    public static void main( String[] args ){
        System.out.println("SchoolMember().MebmberName() = > " + new SchoolMember().MebmberName());
    }
}
public class SchoolMember {

    public String MebmberName() {
        return "abc";
    }
}

- 결과화면

2. 새로운 프로젝에 net.bytebuddy를 불러오기

# https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy

    - 런타임시 java Class들을 동적으로 만들어낼 수 있는 라이브러리

 

Maven Repository: net.bytebuddy » byte-buddy

Byte Buddy is a Java library for creating Java classes at run time. This artifact is a build of Byte Buddy with all ASM dependencies repackaged into its own name space. VersionRepositoryUsagesDate1.10.x1.10.8Central385Feb, 20201.10.7Central25Jan, 20201.10.

mvnrepository.com


2. pom.xml 의존성 추가 (Junit은 필요없습니다.)

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy -->
    <dependency>
      <groupId>net.bytebuddy</groupId>
      <artifactId>byte-buddy</artifactId>
      <version>1.10.8</version>
    </dependency>
  </dependencies>

3.  변경할 함수와 이름 만들어 주기

public class SchoolNameChange {
    // premain
    public static void premain(String agentArgs, Instrumentation inst) {

        new AgentBuilder.Default()
                .type(ElementMatchers.any())
                .transform(new AgentBuilder.Transformer() {
                    @Override
                    public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
                        return builder.method(named("memberName")).intercept(FixedValue.value("Test"));
                    }
                }).installOn(inst);
    }
}

4. pom.xml 의 빌드에 Maven jar 생성 부분 추가

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <archive>
                        <index>true</index>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                        <manifestEntries>
                            <mode>development</mode>
                            <url>${project.url}</url>
                            <key>value</key>
                           <!-- Manifest attribute -->
                          <!-- 애플리케이션 시작시 옵션으로 주기, Package 넣어주기-->
                          <Premain-Class>org.example.SchoolNameChange</Premain-Class>
                          <!-- 클래스 변경 허용 부분 -->
                          <Can-Redefine-Classes>true</Can-Redefine-Classes>
                          <Can-Retransform-Classes>true</Can-Retransform-Classes>
                          <!-- 클래스 변경 허용 부분 -->
                          <!-- Manifest attribute -->
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

5. mvn clean package , jar 파일 생성

 - tistory... .jar 파일 생성

6. 기존의 프로젝트에 VM options에 jar 파일 추가

 [-javaagent:C:\Users\.....\target\tistoryBytebuddyJavaagent-1.0-SNAPSHOT.jar]

 

7. 실행

블로그 이미지

미나미나미

,

- 이 글은 아래의 내용에서 이어지는 내용입니다.

 

[Spring기초] 의존성 주입:DI(DEPENDENCY INJECTION) - 생성자Constructor DI

- 이 글은 아래의 내용에서 이어지는 내용입니다. [Spring기초] 의존성 주입:DI(Dependency Injection) - Setter DI # 의존성 주입 : DI(Dependency Injection) -Setter DI 주입 - Spring 의존성 주입 중 Setter를..

minaminaworld.tistory.com


# 자바로 Bean 만들기 

    - Spring 의존성 주입을 XML 방식이 아닌 자바로 생성하는 방법.

 


1. Package JavaBean , JavaTestBean1.java 

   - 패키지 JavaBean에는 생성할 Bean JavaTestBean1.java를 만든다.

 

package JavaBean;

public class JavaTestBean1 {

	public JavaTestBean1() {
		System.out.println("JavaTestBean1이 생성이 되었습니다.");
	}
}


2. Package config, JavaBeans.java

   - 패키지 config에 JavaBeans.java는 기존의 XML 방식에서 Java형식으로 Bean을 정의한다.

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import JavaBean.JavaTestBean1;

// XML이 방식이 아닌 JAVA의 형식으로 beans.xml을 대체한다.
@Configuration
public class JavaBeans {
		
	// AnnotationConfigApplcationContext 되는 순간 생성.
	// getBean할 때 마다 동일한 객체 전달.	
	@Bean
	public JavaTestBean1 testBean1_1() {
		System.out.println("testBean1_1");
		JavaTestBean1 jtb1 = new JavaTestBean1();
		return jtb1;
	}
	
	// getBean하는 순간에 생성 
	// getBean할 때 마다, 객체 생성.
	@Bean
	@Lazy(true)
	@Scope("prototype")
	public JavaTestBean1 testBean1_2() {
		System.out.println("testBean1_2");
		JavaTestBean1 jtb1 = new JavaTestBean1();
		return jtb1;
	}
	
	// testBean50이라는 이름으로 부르도 명시.
	// name이 없는 경우 메소드명으로 부름(default 경우)
	@Bean(name="testBean50")
	public JavaTestBean1 testBean1_3() {
		System.out.println("testBean1_3");
		System.out.println("naming testBean50");
		JavaTestBean1 jtb1 = new JavaTestBean1();
		return jtb1;
	}
		
	@Bean(name="testBean100")
	@Lazy(true)
	public JavaTestBean1 testBean1_4() {
		System.out.println("testBean1_4");
		System.out.println("naming testBean100");
		JavaTestBean1 jtb1 = new JavaTestBean1();
		return jtb1;
	}
}

 

 


3. Main.java

package main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import JavaBean.JavaTestBean1;
import config.JavaBeans;
import constructorDI.StudentData;
import constructorDI.StudentTestBean;

public class Main {

	public static void main(String[] args) {
		// JAVA 파일을 사용하는 방식
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaBeans.class);
		JavaTestBean1 testBean1_1 = ctx.getBean("testBean1_1", JavaTestBean1.class);
		System.out.printf("testBean1_1 = > %s\n", testBean1_1);
		System.out.println("-------------------------------------------");

		JavaTestBean1 testBean1_2 = ctx.getBean("testBean1_2", JavaTestBean1.class);
		System.out.printf("testBean1_2 = > %s\n", testBean1_2);
		System.out.println("-------------------------------------------");

		JavaTestBean1 testBean50 = ctx.getBean("testBean50", JavaTestBean1.class);
		System.out.printf("testBean50 = > %s\n", testBean50);
		System.out.println("-------------------------------------------");

		JavaTestBean1 testBean100 = ctx.getBean("testBean100", JavaTestBean1.class);
		System.out.printf("testBean100 = > %s\n", testBean100);
		System.out.println("-------------------------------------------");

		ctx.close();
		System.out.println("-ctx.close() 됨");
	}
}

4. 결과화면


 

블로그 이미지

미나미나미

,