매일 조금씩

01/26 ! - Spring(3) : DI의 lifecycle, AOP - DI, AspectJ, Spring API(annotation) 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

01/26 ! - Spring(3) : DI의 lifecycle, AOP - DI, AspectJ, Spring API(annotation)

mezo 2021. 2. 25. 19:58
728x90
반응형

Java framwork 최신 설정

- xml 

        - 기존

- annotaiton

        - POJO

 

DI -  객체 생성 (초기화) 방법

             생성자

             setter

                 - 주입

 

             => 소멸

 

             => 라이프사이클 => spring framework

                                         - thread

                                          * database pooling

     

 


 

2. DI (Dependency Inject)

...

 어제에 이어서

...

 

[ Spring Bean Life Cycle ( bean 생명 주기 관리) ]

1) lifecycle 순서대로 찍기

> lifecycle1

진짜 순서대로 돌아가는지 알기 위해서 여러가지 메서드를 implements 해야한다. 

다음의 클래스들을 import시키면서 WriteAction에 implements 한다.

그리고 WriteAction클래스에 뜬 오류를 클릭하면 추가한 다음 클래스들에 대한 메서드가 생기면서 오류가 사라진다.

ApplicationContextAware, BeanFactoryAware, BeanNameAware, DisposableBean, InitializingBean

 

> com.exam.lifecycle1 > context.xml

<bean id="action" class="com.exam.lifecycle1.model.WriteAction" scope="prototype">
    <property name="writer">
        <value>Hello Writer</value>
    </property>
</bean>

> com.exam.lifecycle1.model >WriteAction.java

package com.exam.lifecycle1.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class WriteAction implements BoardAction, 
			ApplicationContextAware, BeanFactoryAware, 
			BeanNameAware, DisposableBean, InitializingBean {
	
	private String writer;
	
	private String beanName;
	private BeanFactory beanFactory;
	
	public WriteAction() {
		System.out.println("1. 빈의 생성자 호출");
	}
	
	public void setWriter(String writer) {
		System.out.println("2. setWriter(String writer) 호출");
		
		this.writer = writer;
	}
	
	public void execute() {
		System.out.println("*.execute() 호출");
		
		System.out.println("beanName : " + beanName);
		System.out.println("beanFactory : " + beanFactory);
		
		System.out.println("writer : " + writer);
	}

	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("7. afterPropertiesSet() 호출");
	}

	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("10. destroy() 호출");
	}

	public void setBeanName(String name) {
		// TODO Auto-generated method stub
		System.out.println("3. setBeanName(String name) 호출");
		
		this.beanName = name;
	}

	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("4. setBeanFactory(BeanFactory beanFactory) 호출");
		
		this.beanFactory = beanFactory;
	}

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("5. setApplicationContext(ApplicationContext applicationContext) 호출");
	}
}

 

 

2) 전처리 후처리

 

1) context.xml에서 init-method, destroy-method 속성 추가

<bean id="action" class="com.exam.lifecycle1.model.WriteAction" scope="prototype" init-method="init_method" destroy-method="destroy_method">
    <property name="writer">
        <value>Hello Writer</value>
    </property>
</bean>

 

2) WriteAction.java 에 아래의 init_method(), detroy_method() 추가

public void init_method() {
    System.out.println("8. init_method() 호출");
}

public void destroy_method() {
    System.out.println("11. destroy_method() 호출");
}

 

이렇게 까지만 하면 detroy_method가 실행되지 않는다. 

3) 다음처럼 ctx.removeBeanDefinition("action"); 를 추가

public static void main( String[] args )
{
    GenericXmlApplicationContext ctx
        = new GenericXmlApplicationContext("classpath:com/exam/lifecycle1/context.xml");

    WriteAction action = (WriteAction)ctx.getBean("action");
    action.execute();

    // bean 메모리에서 제거 
    ctx.removeBeanDefinition("action");

    // 컨테이너 제거
    ctx.close();
}

4) context.xml에서 scope="singleton"으로 바꿔준다.

<bean id="action" class="com.exam.lifecycle1.model.WriteAction" scope="singleton" init-method="init_method" destroy-method="destroy_method">
    <property name="writer">
        <value>Hello Writer</value>
    </property>
</bean>

 

 

3) 필요한 곳에만 써주기

전처리 후처리가 빈의 전처리, 후처리 인지 확인한다.

 

ListAction.java라는 새로운 클래스를 만든다.

> com.exam.lifecycle1.model >ListAction.java

package com.exam.lifecycle1.model;

public class ListAction implements BoardAction{
	private String writer;
	
	public ListAction() {

		System.out.println("ListAction 생성자 호출");
	}
	
	public void setWriter(String writer) {
		System.out.println("setWriter(String writer) 호출");
		this.writer = writer;
	}
	
	public void execute() {
		System.out.println(writer);
	}
	
	public void init_method() {
		System.out.println("빈의 사용자 초기화");
	}
	
	public void destroy_method() {
		System.out.println("빈의 사용자 제거");
	}
}

 

> com.exam.lifecycle1 > context.xml

<bean id="action" class="com.exam.lifecycle1.model.ListAction" scope="singleton" init-method="init_method" destroy-method="destroy_method">
    <property name="writer">
        <value>Hello Writer</value>
    </property>
</bean>

 

 

 

 

 

 

 

4) 외부클래스에서 빈의 전처리, 후처리

1) CustomBeanPostProcessor.java 만들기

 

2) context.xml 에 다음 코드 추가

<bean class="com.exam.lifecycle1.CustomBeanPostProcessor" />

 

 

 

 

 

5) context.xml에서 init-method, destroy-method로 전처리, 후처리 했던걸 annotation으로 구현

다음의 태그를 사용한다.

@Bean(initMethod="init_method", destroyMethod="destroy_method")

> com.exam.lifecycle1.config > BeanConfig.java

package com.exam.lifecycle1.config;

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

import com.exam.lifecycle1.model.ListAction;

public class BeanConfig {
	
	@Bean(initMethod="init_method", destroyMethod="destroy_method")
	@Scope("singleton")
	public ListAction action() {
		ListAction listAction = new ListAction();
		listAction.setWriter("Hello Writer");
		return listAction;
	}
}

 

 

 

 

 

 

 

3. AOP (Aspect Oriented Programming) 

'관점 중심 프로그래밍'이다.

관점이란, 공통 적용 사항(전처리, 후처리 해야할일) 이다.

그 예로 보안 같은 것이 있다.

AOP를 가장 잘 설명하는건 Servlet의 filter이다.

Servlet filter가 하는일이 프로그램 전체에 대한 전처리나 후처리다. 

위의 전처리, 후처리는 beans에 대한 것이기 때문에 다르다.

 

proxy

 

  • advice - 적용시점 (전/후)
  • joinpoint - advice를 적용할 지점 (어느 메서드)
  • pointcut - 문법표현
  • weaving - aop를 적용해라

 

[ 구현방법 ]

1. DI

2. AspectJ

3. Spring 자체 API

 

around - 전후처리

before - 전처리

after - 후처리

after-throwing - 후처리 에러


 

3-1. DI

3-2. AspectJ

3-3. Spring 자체 API

 


3-1. DI 로 AOP 구현

Arround Advisor 

전처리와 후처리를 모두다 해준다.

 

> aop1

 

1) 전처리, 후처리를 받을 메서드가 포함된 클래스를 만든다.

> com.exam.aop1.model > BasicAction.java

package com.exam.aop2.model;

public interface BoardAction {
	public abstract void execute();
}

> com.exam.aop1.model > WriteAction.java

package com.exam.aop2.model;

public class WriteAction implements BoardAction {

	private String writer;
	
	public void setWriter(String writer) {
		this.writer = writer;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		System.out.println("execute() 시작");
		System.out.println(writer);
		System.out.println("execute() 끝");
	}
}

 

2) 전처리, 후처리를 해줄 Adivisor  클래스들을 만든다.

반드시 MethodInterceptor를 interface로 해서 만들어야한다.

 

> com.exam.aop1.advice > BasicAdvice.java

package com.exam.aop1.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class BasicAdvice implements MethodInterceptor {

	public Object invoke(MethodInvocation invocation) throws Throwable {
		// TODO Auto-generated method stub
		
		// Arround Advice 방식 (전/후를 모두)
		
		// 전처리
		System.out.println("전처리 구간");
		Object rtnObj = invocation.proceed();
		
		// 후처리
		System.out.println("후처리 구간");
		
		return rtnObj;
	}

}

 

> com.exam.aop1.advice > BasicAdvice2.java

package com.exam.aop1.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class BasicAdvice2 implements MethodInterceptor {

	public Object invoke(MethodInvocation invocation) throws Throwable {
		// TODO Auto-generated method stub
		
		// Arround Advice 방식 (전/후를 모두)
		
		// 전처리
		System.out.println("전처리 구간 2");
		Object rtnObj = invocation.proceed();
		
		// 후처리
		System.out.println("후처리 구간 2");
		
		// 반드시!
		return rtnObj;
	}

}

 

> com.exam.aop1.advice > TimeAdvice.java

package com.exam.aop1.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;

public class TimeAdvice implements MethodInterceptor {

	public Object invoke(MethodInvocation invocation) throws Throwable {
		
		// 메서드명 가져오기
		String methodName = invocation.getMethod().getName();
		
		System.out.println(methodName + " : 호출시작");
		
		// ----- 메서드가 실행되는 시간 측정
		StopWatch stopWatch = new StopWatch();
		
		// 측정 시작
		stopWatch.start(methodName);
		
		Object rtnObj = invocation.proceed();
	
		stopWatch.stop();
		// 측정 끝
		
		
		System.out.println("처리시간 : " + stopWatch.getTotalTimeSeconds() + " 초");
		
		System.out.println(methodName + " : 호출끝");
		
		return rtnObj;
	}

}

 

 

3) context.xml에서 Advisor들의 적용 지점과 순서를 정해준다.

> com.exam.aop1 > context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">

	<!-- aop -->
	<bean id="basicAdvice" class="com.exam.aop1.advice.BasicAdvice" />
	<bean id="basicAdvice2" class="com.exam.aop1.advice.BasicAdvice2" />
	<bean id="timeAdvice" class="com.exam.aop1.advice.TimeAdvice" />
	
	<!-- execute 메서드가 실행되면  basicAdvice를 실행시켜라 -->
	<bean id="pointcutAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor" >
		<property name="advice">
			<ref bean="basicAdvice" />
		</property>
		<property name="pointcut">
			<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
				<property name="pattern">
					<value>.*execute.*</value>
				</property>
			</bean>
		</property>
	</bean>
	
	<!-- execute 메서드가 실행되면  basicAdvice2를 실행시켜라 -->
	<bean id="pointcutAdvisor2" class="org.springframework.aop.support.DefaultPointcutAdvisor" >
		<property name="advice">
			<ref bean="basicAdvice2" />
		</property>
		<property name="pointcut">
			<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
				<property name="pattern">
					<value>.*execute.*</value>
				</property>
			</bean>
		</property>
	</bean>
	
	<!-- execute 메서드가 실행되면  timeAdvice를 실행시켜라 -->
	<!-- execute 메서드 실행시간 확인 -->
	<bean id="pointcutAdvisor3" class="org.springframework.aop.support.DefaultPointcutAdvisor" >
		<property name="advice">
			<ref bean="timeAdvice" />
		</property>
		<property name="pointcut">
			<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
				<property name="pattern">
					<value>.*execute.*</value>
				</property>
			</bean>
		</property>
	</bean>

	<!-- WriteAction 초기화 -->
	<bean id="action" class="com.exam.aop1.model.WriteAction">
		<property name="writer">
			<value>홍길동</value>
		</property>
	</bean>
	
	
	<!-- aop => 객체 -->
	<!-- action을 실행시키고 advisor의 실행 순서를 정함 -->
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="action"/>
		<property name="interceptorNames">
			<!-- list 내의 순서대로 advisor가 실행된다. -->
			<list>
				<value>pointcutAdvisor</value>
				<value>pointcutAdvisor2</value>
				<value>pointcutAdvisor3</value>
			</list>
		</property>
	</bean>
</beans>

 

4) main 메서드에서 getBean으로 proxy를 넣어준다.

> com.exam.aop1 > App.java

package com.exam.aop1;

import org.springframework.context.support.GenericXmlApplicationContext;

import com.exam.aop1.model.BoardAction;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
    	GenericXmlApplicationContext ctx
    		=	 new GenericXmlApplicationContext("classpath:com/exam/aop1/context.xml");
    	
    	
    	// proxy, action
    	// proxy를 넣어줌으로써 bean 생성 실행 전에 Arround Advisor를 거치게 된다.
    	BoardAction action = (BoardAction)ctx.getBean("proxy");
    	
    	// pointcutAdvisor, pointcutAdvisor2
    	action.execute();
    	
    	ctx.close();
    }
}

proxy는 링크같은 것에서 바로 가지 않고 중간에 거쳐서 가는걸 말한다.

여기서 proxy가 적용된 것을 알수 있다.

 

 

 

3-2. AspectJ로  AOP 구현

> aop2

 

pom.xml에 다음코드를 추가, 저장한다.

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.2</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.2</version>
</dependency>

 

1) 전처리, 후처리를 받을 메서드가 포함된 클래스를 만든다.

( 3-1과 동일 )

 

2) 전처리, 후처리를 해줄 Adivisor 클래스들을 만든다.

> com.exam.aop2..advice > BasicAdvice1.java

package com.exam.aop2.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class BasicAdvice1 {
	// 전처리, 후처리 다하겠다.
	public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
		
		System.out.println("전처리");
		
		Object rtnObj = joinPoint.proceed();
		
		System.out.println("후처리");
		
		return rtnObj;
	}
}

> com.exam.aop2..advice > BasicAdvice2.java

package com.exam.aop2.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class BasicAdvice2 {
	// 전처리, 후처리 다하겠다.
	public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
		
		System.out.println("전처리 2");
		
		Object rtnObj = joinPoint.proceed();
		
		System.out.println("후처리 2");
		
		return rtnObj;
	}
}

 

3) context.xml을 만들 때 beans과 함께 aop를 추가해서 만든다.

<aop:config>  안에 <aop:aspect>를 넣어서 aop를 가동시킨다.

<aop:aspect> 안엔  적용지점인 <aop:pointcut> 와 적용 시점인 <aop:around>가 있다.

> com.exam.aop2 > context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

	<bean id="action" class="com.exam.aop2.model.WriteAction">
		<property name="writer" value="홍길동" />
	</bean>

	<bean id="basicAdvice1" class="com.exam.aop2.advice.BasicAdvice1" />
	<bean id="basicAdvice2" class="com.exam.aop2.advice.BasicAdvice2" />
	
	<!-- AOP -->
	<aop:config>
		<!-- 쓰인 순서대로 실행된다. -->
		<!-- basicAdivce1 클래스를 통해서 execute()의 전처리 후처리를 logAround()로 가동 시켜줘! -->
		<aop:aspect ref="basicAdvice1">
			<aop:pointcut id="pointCut" expression="execution(* execute())" />
			<aop:around method="logAround" pointcut-ref="pointCut" />
		</aop:aspect>
		<!-- basicAdivce2 클래스를 통해서 execute()의 전처리 후처리를 logAround()로 가동 시켜줘! -->
		<aop:aspect ref="basicAdvice2">
			<aop:pointcut id="pointCut" expression="execution(* execute())" />
			<aop:around method="logAround" pointcut-ref="pointCut" />
		</aop:aspect>
	</aop:config>
</beans>

 

4) main 메서드가 있는 클래스에서 실행 시킨다.

> com.exam.aop2 > App.java

package com.exam.aop2;

import org.springframework.context.support.GenericXmlApplicationContext;

import com.exam.aop2.model.BoardAction;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
    	GenericXmlApplicationContext ctx
		=	 new GenericXmlApplicationContext("classpath:com/exam/aop2/context.xml");
	
	
		BoardAction action = (BoardAction)ctx.getBean("action");
		action.execute();
		
		ctx.removeBeanDefinition("action");
		
		ctx.close();
    }
}

 

 

3-1과 결과가 같다.

 

 

5) AOP하나로 처리 해주고 싶은 메서드가  두개일때

만약 AOP하나로 처리 해주고 싶은 메서드가 execute1(), execute2()이렇게 두개일때

aop:pointcut의 메서드이름에 wild card문자인 *를 사용해서 다음과 같이 처리하면 두개가 실행이 된다.

<aop:pointcut id="pointCut" expression="execution(* execute*())" />

> com.exam.aop2 > App.java

package com.exam.aop2;

import org.springframework.context.support.GenericXmlApplicationContext;

import com.exam.aop2.model.BoardAction;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
    	GenericXmlApplicationContext ctx
		=	 new GenericXmlApplicationContext("classpath:com/exam/aop2/context.xml");
	
	
		BoardAction action = (BoardAction)ctx.getBean("action");
		action.execute1();
		action.execute2();
		
		ctx.removeBeanDefinition("action");
		
		ctx.close();
    }
}

각각 전처리, 후처리가 된 것을 확인 할 수 있다.

 

 

6) around 말고 전, 후 처리 따로 하고 싶을 때 before, after

before, after advice 메서드를 advice 클래스에 만들어준후,

<aop:before>, <aop:after> 사용한다.

먼저 around 일땐 다음과 같다.

<aop:around method="logAround" pointcut-ref="pointCut" />

그러나 before 와 after 일땐 다음과 같다.

ㅇ before

<aop:before method="before" pointcut-ref="pointCut" />

ㅇ after

<aop:after method="after" pointcut-ref="pointCut" />

 

3-3. Spring api 로 AOP 구현

Annotation기법이다.

 

> aop3

 

pom.xml에 다음코드를 추가, 저장한다.

AspectJ일때와 달리 weaver만 추가한다.

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.2</version>
</dependency>

 

1) 전처리, 후처리를 받을 메서드가 포함된 클래스를 만든다.

(3-2와 동일)

> com.exam.aop3.model > BoardAction.java

> com.exam.aop3.model > WriteAction.java

 

2) 전처리, 후처리를 할 Advice 클래스를 만든다.

클래스 위에 @Aspect 와 함께 @Around, @Before, @After 를 원하는 대로 적어준다.

> com.exam.aop3.advice > BasicAdvice1.java

package com.exam.aop3.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class BasicAdvice1 {
	
	@Around("execution(* execute1())")
	public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
		
		System.out.println("전처리");
		
		Object rtnObj = joinPoint.proceed();
		
		System.out.println("후처리");

		return rtnObj;
	}
    
    	@Before("execution(* execute2())")
	public void before() {
		System.out.println("before() 호출");
	}
	
	@After("execution(* execute2())")
	public void after() {
		System.out.println("after() 호출");
	}
}
}

 

> com.exam.aop3.advice > BasicAdvice2.java

package com.exam.aop3.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class BasicAdvice2 {
	
	@Around("execution(* execute1())")
	public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
		
		System.out.println("전처리 2");
		
		Object rtnObj = joinPoint.proceed();
		
		System.out.println("후처리 2");

		return rtnObj;
	}
}

 

 

3) context.xml을 만들 때 beans과 함께 aop를 추가해서 만든다.

AOP가 오는 자리에 아래의 한줄만 적어주면 된다.

<aop:aspectj-autoproxy />

 

> com.exam.aop3 > context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

	<bean id="action" class="com.exam.aop3.model.WriteAction" >
		<property name="writer" value="홍길동" />
	</bean>
	
	<bean id="basicAdvice1" class="com.exam.aop3.advice.BasicAdvice1" />
	<bean id="basicAdvice2" class="com.exam.aop3.advice.BasicAdvice2" />
	
	<aop:aspectj-autoproxy />

</beans>

 

 

4) main 메서드가 있는 클래스에서 실행 시킨다.

> com.exam.aop3 > App.java

package com.exam.aop3;

import org.springframework.context.support.GenericXmlApplicationContext;

import com.exam.aop3.model.BoardAction;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
    	GenericXmlApplicationContext ctx
		=	 new GenericXmlApplicationContext("classpath:com/exam/aop3/context.xml");
	
	
		BoardAction action = (BoardAction)ctx.getBean("action");
		action.execute1();
		action.execute2();
		
		ctx.removeBeanDefinition("action");
		
		ctx.close();
    }
}

5) context.xml 파일을 전부 annotation으로 쓴다면 ?

<aop:aspectj-autoproxy />

 

context.xml에서 썼던 위의 태그를 아래의 annotation으로 대신한다.

@EnableAspectJAutoProxy

 

> com.exam.aop3.config > BeanConfig.java

package com.exam.aop3.config;

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

import com.exam.aop3.model.BoardAction;
import com.exam.aop3.model.WriteAction;

import com.exam.aop3.advice.BasicAdvice1;
import com.exam.aop3.advice.BasicAdvice2;

@Configuration
@Scope("prototype")
@EnableAspectJAutoProxy
public class BeanConfig {
	
    	// 프로퍼티 값 전달
	@Bean
	public BoardAction action() {
		WriteAction action = new WriteAction();
		action.setWriter("홍길동");
		return action;
	}
	
	@Bean
	public BasicAdvice1 BasicAdvice1() {
		return new BasicAdvice1();
	}
	
	@Bean
	public BasicAdvice2 BasicAdvice2() {
		return new BasicAdvice2();
	}
}

 

> com.exam.aop3 > App.java

package com.exam.aop3;

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

import com.exam.aop3.model.BoardAction;
import com.exam.aop3.config.BeanConfig;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
    	//GenericXmlApplicationContext ctx
		//=	 new GenericXmlApplicationContext("classpath:com/exam/aop3/context.xml");
    	
    	// Annotation 기법일때 (context.xml을 쓰지 않을때)
    	AnnotationConfigApplicationContext ctx
		= new AnnotationConfigApplicationContext( BeanConfig.class);
	
		BoardAction action = (BoardAction)ctx.getBean("action");
		action.execute1();
		action.execute2();
		
		ctx.removeBeanDefinition("action");
		
		ctx.close();
    }
}

 

 

응용문제) 구구단 1~100단까지 얼마나 시간이 걸리는지 annotation으로 구현하기

 

728x90
반응형