当与组件

时间:2017-12-14 16:43:02

标签: java spring spring-boot aspectj spring-aop

我遇到的问题@Profile未对使用@Aspect注释的方面生效。即使我的弹簧配置文件没有被激活,也会始终调用方面,我已经查看了下面的多个来源,似乎声称@Profile@Aspect应该允许根据配置文件启用或禁用方面激活。

http://city81.blogspot.co.uk/2012/05/using-spring-profile-with.html

using Spring @Profile in @Aspect

以下是我的代码;

DummyAspect

@Component
@Profile("sdfkljklf")
@Aspect
public class DummyAspect implements InitializingBean {
    public DummyAspect() {
        System.out.println("Constructor: " + getClass().getName());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterpropertiesSet: " + getClass().getName());
    }

    @Pointcut("execution(public * spring.desai.common.repository.*.*(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void beforeMethod(final JoinPoint jp) {
        System.out.println("Entering: " + jp.toLongString());
    }

    @AfterReturning(pointcut = "pointcut()", returning = "retValue")
    public void afterMethod(final JoinPoint jp, Object retValue) {
        System.out.println("Exiting " + jp.toLongString());
    }
}

根据我的理解,只有在激活配置文件sdfkljklf时才应初始化并应用此方面。然而,无论何时调用任何符合条件的存储库方法,我都可以从控制台中的方面看到系统输出条目。这是一个春季启动应用程序,所以我可以看到以下内容,其中说明sdfkljklf未被激活。

2017-12-14 16:25:19,374 [INFO ] SpringBootApp : The following profiles are active: jdbc,embedded,rmiEnabled

另一个有趣的观察是,这个方面没有在应用程序部署时初始化,而是在第一次调用存储库方法时才进行初始化。我通过在构造函数和afterPropertiesSet方法中放置系统输出日志来找到它。下面是应用程序完成启动时的日志摘录,然后我调用我的休息端点,然后调用服务 - >存储库 - >数据库;

2017-12-14 16:27:48,325 [INFO ] TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-12-14 16:27:48,340 [INFO ] SpringBootApp : Started SpringBootApp in 5.13 seconds (JVM running for 5.611)
Dec 14, 2017 4:27:49 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-12-14 16:27:49,873 [INFO ] DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2017-12-14 16:27:49,891 [INFO ] DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 17 ms
2017-12-14 16:27:49,946 [INFO ] HomeController : returning home
2017-12-14 16:27:50,432 [WARN ] PageNotFound : No mapping found for HTTP request with URI [/web-console/resources/style.css] in DispatcherServlet with name 'dispatcherServlet'
Constructor: dummy.pckg.DummyAspect
Entering: execution(public spring.desai.common.model.Persistable spring.desai.common.repository.impl.jdbc.BaseJdbcRepository.findById(java.lang.String))
Exiting execution(public spring.desai.common.model.Persistable spring.desai.common.repository.impl.jdbc.BaseJdbcRepository.findById(java.lang.String))
Entering: execution(public java.util.Collection spring.desai.common.repository.impl.jdbc.SubjectRepositoryImpl.getSubjectsForStudentId(java.lang.String))
Exiting execution(public java.util.Collection spring.desai.common.repository.impl.jdbc.SubjectRepositoryImpl.getSubjectsForStudentId(java.lang.String))
Entering: execution(public java.util.Collection spring.desai.common.repository.impl.jdbc.PaymentRepositoryImpl.findByStudentId(java.lang.String))
Exiting execution(public java.util.Collection spring.desai.common.repository.impl.jdbc.PaymentRepositoryImpl.findByStudentId(java.lang.String))
Entering: execution(public java.util.Collection spring.desai.common.repository.impl.jdbc.ScholarshipRepositoryImpl.findByStudentId(java.lang.String))
Exiting execution(public java.util.Collection spring.desai.common.repository.impl.jdbc.ScholarshipRepositoryImpl.findByStudentId(java.lang.String))

没有堆栈跟踪,因为没有错误但是我无法找出导致它忽略@Profile注释的原因?

我试过以下无济于事;

  • 清理项目
  • 重新启动STS并通过在重新启动时手动删除目标文件夹来构建。
  • 更改了方面类的名称,以确保它没有被任何硬编码bean定义初始化。
  • 将其放置在具有不同根目录的完全不同的包中,以确保它不会被任何错误的组件扫描扫描
  • 启用DEBUG登录整个spring框架,以查看在此方面初始化之前记录的内容,但没有任何内容接近根本原因。
  • 通过以下代码在我的rest控制器和bean定义名称的打印列表中自动连接应用程序上下文。然而,这个方面在部署时没有初始化,所以它不在那里;

    for(String s : context.getBeanDefinitionNames()) {   
        System.out.println(s);
    }
    

我在java 7上使用了aspectj 1.8.6和spring 4.3.2以及sprint-boot 1.4.0。我们将非常感谢任何帮助。如果需要更多详细信息,请告诉我们;

2 个答案:

答案 0 :(得分:2)

这对我有用:

@Configuration
public class AopConfiguration {

    @Aspect
    @EnableAspectJAutoProxy
    @Profile("my_profile")
    static class AopRule1 {

        @Around("/*some rules*/")
        public Object doAop(ProceedingJoinPoint joinPoint) throws Throwable {
        //logic
        }
    }
}

答案 1 :(得分:1)

我的猜测是你正确设法实际使用aspectj而不是spring-aop(两种截然不同的解决方案经常混为一谈),但是,aspectj是一种完全独立于弹簧的技术而且它不会考虑配置文件选择中的弹簧特定注释。 Spring的@Profile注释可能适用于spring-aop,因为spring本身将在spring bean的周围创建代理,以便Spring-aop工作,但是使用native nativej并不是这样的。

您需要在您的建议中进行运行时测试,以确定您是否希望您的方面处于活动状态,可能会在true中设置一个布尔标记afterPropertiesSet(),并且默认情况下保留标志false,这样如果弹簧没有配置方面,它就不会运行。