2016-04-21 2 views
2

Моего класса ApplicationПроблем с АОП в весенних загрузках

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); 
    } 

} 

Моего аспект класс

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> 

Это файлы в моем приложении загрузки весной. Я хочу регистрировать все общедоступные методы в своем приложении с помощью 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 

ответ

6

Вашего Pointcut настолько родовой:

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

Это посоветует все доступные публичные методы каждого класса по классам, каждый из них! К сожалению, Spring AOP не может сделать необходимый прокси-сервер для некоторых нынешних классов на пути к классам (Поскольку они не выполняют какой-либо интерфейс и final), следовательно, ошибка:

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

Если ограничить Pointcut к просто посоветуйте свои занятия, с вами все будет в порядке!

+0

Он работал. Я просто перефразирую свое понимание, исправлю меня, если я ошибаюсь. Всякий раз, когда мы советуем некоторый метод в классе, весенний контейнер создает прокси-класс, расширяя целевой класс и реализуя совет и метод с использованием прокси-класса. Поскольку я консультирую все общедоступные методы, он также создает прокси-класс для конечных классов. – Manu

+0

Весна будет использовать разные механизмы для создания этого прокси. Один из них - создать подкласс из целевого класса. Я предполагаю, что реализация интерфейса и прокси AspectJ также являются опциями. –

+0

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

7

Ваш allPublicMethods pointcut слишком широк. Он применяется к каждому общественному методу каждого класса. Один класс, который соответствует org.springframework.boot.autoconfigure.AutoConfigurationPackages$BasePackages. Он объявлен как final, который предотвращает применение к нему рекомендаций.

Вы должны сузить сферу вашего среза точек, например, лишь применяя его к коду в вашем собственном com.example пакете:

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

Я новичок до весны. Не могли бы вы рассказать мне, почему мы используем эту аннотацию @EnableAspectJAutoProxy. мы можем только советы весной управляемые бобы? – Manu

Смежные вопросы