일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- deque
- 리소스모니터링
- 스프링부트
- priority_queue
- Calendar
- GC로그수집
- List
- union_find
- scanner
- javascript
- CSS
- Properties
- 힙덤프
- date
- alter
- string
- NIO
- set
- JPA
- 큐
- sql
- dfs
- 스택
- BFS
- Java
- spring boot
- math
- Union-find
- map
- html
- Today
- Total
매일 조금씩
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:58Java 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으로 구현하기