[SPRING] 봄 부팅시 Aop 관련 문제
SPRING봄 부팅시 Aop 관련 문제
내 응용 프로그램 클래스
import com.example.haha.Haha;
import com.example.hehe.Hehe;
import com.example.logging.Logging;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy
public class DemoApplication {
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
for(String name:ctx.getBeanDefinitionNames()){
System.out.println(name);
}
Haha haha = (Haha)ctx.getBean("hh");
haha.haha1();
haha.haha2();
return;
}
}
Haha.java
package com.example.haha;
import org.springframework.stereotype.Component;
/**
* Created by vamsi on 4/21/16.
*/
@Component("hh")
public class Haha {
public Haha(){
}
public void haha1() throws InterruptedException {
System.out.println("In method haha1");
Thread.sleep(1000);
}
public void haha2() throws InterruptedException {
System.out.println("In method haha2");
Thread.sleep(2000);
}
}
My Aspect 클래스
package com.example.logging;
import org.apache.commons.logging.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* Created by vamsi on 4/21/16.
*/
@Aspect
@Component
public class Logging {
public Logging() {
}
@Pointcut("execution(public * *(..))")
private void allPublicMethods(){}
@Around("allPublicMethods()")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
System.out.println(pjp.getSignature() +"begins");
Object output = pjp.proceed();
System.out.println(pjp.getSignature()+"completed.");
long elapsedTime = System.currentTimeMillis() - start;
System.out.println("Method execution time: " + elapsedTime + " milliseconds.");
return output;
}
}
Pom.hml
<?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>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
이것들은 내 스프링 부팅 응용 프로그램의 파일입니다. 내 응용 프로그램에서 AOP를 사용하여 모든 공용 메소드를보고 싶습니다. 내가 응용 프로그램을 실행할 때 다음 오류가 발생합니다.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.AutoConfigurationPackages': Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at com.example.DemoApplication.main(DemoApplication.java:18) [classes/:na]
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:213) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:468) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:349) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:298) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 14 common frames omitted
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:457) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$ClassLoaderAwareUndeclaredThrowableStrategy.generate(CglibAopProxy.java:990) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:231) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:378) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:318) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:55) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:203) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 21 common frames omitted
해결법
-
==============================
1.귀하의 Pointcut은 매우 일반적입니다 :
귀하의 Pointcut은 매우 일반적입니다 :
@Pointcut("execution(public * *(..))")
그것은 classpath에있는 모든 클래스의 사용 가능한 모든 public 메소드를 조언 할 것입니다. 아쉽게도 Spring AOP는 classpath에 존재하는 클래스들에 대해 필요한 프록시를 만들 수 없다 (왜냐하면 그들은 어떤 인터페이스도 구현하지 않고 최종적이기 때문에). 따라서 오류가 발생한다 :
pointcut을 클래스에 대한 조언으로 제한한다면, 괜찮을 것입니다!
-
==============================
2.allPublicMethods pointcut이 너무 넓습니다. 그것은 모든 클래스의 모든 public 메소드에 적용됩니다. 일치하는 클래스는 org.springframework.boot.autoconfigure.AutoConfigurationPackages $ BasePackages입니다. 조언이 적용되는 것을 막는 final로 선언되었습니다.
allPublicMethods pointcut이 너무 넓습니다. 그것은 모든 클래스의 모든 public 메소드에 적용됩니다. 일치하는 클래스는 org.springframework.boot.autoconfigure.AutoConfigurationPackages $ BasePackages입니다. 조언이 적용되는 것을 막는 final로 선언되었습니다.
예를 들어 자신의 com.example 패키지에있는 코드에만 적용하여 pointcut의 범위를 좁혀 야합니다.
@Pointcut("execution(public * com.example..*(..))")
from https://stackoverflow.com/questions/36775611/problems-with-aop-in-spring-boot by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring의 @RepositoryRestResource REST API를 통해 다 - 대 - 다 관계에 요소를 추가하는 방법? (0) | 2019.04.10 |
---|---|
[SPRING] @Component와 @Autowired를 사용할 때 스프링 빈 원시 속성? (0) | 2019.04.10 |
[SPRING] Spring 애플리케이션의 예외 처리 위치 (0) | 2019.04.10 |
[SPRING] SessionRegistry로 사용자 로그인하기 (0) | 2019.04.10 |
[SPRING] 봄 부팅로드 orm.xml (0) | 2019.04.10 |