2016-04-21 9 views
2

Meine AnwendungsklasseProbleme mit Aop im Frühjahr Boot

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 Klasse

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.xml

<?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> 

Dies sind die Dateien in meiner Spring-Boot-Anwendung. Ich möchte alle öffentlichen Methoden in meiner Anwendung mit AOP anmelden. Bu, wenn ich meine Anwendung ausführe gibt es den folgenden Fehler.

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 

Antwort

6

Ihre Pointcut ist so generic:

@Pointcut("execution(public * *(..))") 

, dass alle verfügbaren öffentlichen Methoden jeder Klasse auf dem Classpath beraten wird, jeder einzelne von ihnen! Leider kann Frühling AOP nicht für einige vorhandenen Klassen auf dem Classpath macht die erforderliche Proxy (Da sie keine Schnittstelle und bin final Implementierung), daher der Fehler:

Cannot subclass final class org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages

Wenn Sie Ihren pointcut beschränken, nur Beraten Sie Ihren Unterricht, Ihnen geht es gut!

+0

Es funktionierte. Ich werde nur mein Verständnis umformulieren, mich korrigieren, wenn ich falsch liege. Wann immer wir eine Methode in einer Klasse empfehlen, erstellt der Spring-Container eine Proxy-Klasse, indem er die Zielklasse erweitert und den Advice und die Methode mithilfe der Proxy-Klasse implementiert. Da ich alle öffentlichen Methoden berate, erstellt es auch eine Proxy-Klasse für die letzten Klassen. – Manu

+0

Spring verwendet verschiedene Mechanismen zum Erstellen dieses Proxys. Eine davon ist das Erstellen einer Unterklasse aus der Zielklasse. Ich denke, die Implementierung der Schnittstelle und AspectJ Proxies sind auch Optionen. –

+0

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#aop-introduction-proxies –

7

Ihr allPublicMethods Punkt ist zu breit. Es wird auf jede öffentliche Methode jeder Klasse angewendet. Eine passende Klasse ist org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages. Es wird als final deklariert, was verhindert, dass der Hinweis darauf angewendet wird.

Sie sollen den Umfang Ihrer pointcut verengen, zum Beispiel durch es nur Code in Ihrem eigenen com.example Paket Anwendung:

@Pointcut("execution(public * com.example..*(..))") 
+0

Ich bin neu Federn. Können Sie mir bitte sagen, warum wir diese Annotation @EnableAspectJAutoProxy verwenden. können wir nur im Frühjahr gemanagte Bohnen richtig beraten? – Manu

Verwandte Themen