首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当与组件上的@方面耦合时,Spring忽略@Profile注释

当与组件上的@方面耦合时,Spring忽略@Profile注释
EN

Stack Overflow用户
提问于 2017-12-14 16:43:02
回答 2查看 1.2K关注 0票数 1

我的问题是@Profile在用@Aspect注释的方面上不起作用。即使我的spring配置文件未被激活,方面也将始终被调用,我已经查看了多个源,如下所示,它似乎声称@Profile@Aspect应该允许基于概要文件激活启用或禁用方面。

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

using Spring @Profile in @Aspect

下面是我的代码;

DummyAspect

代码语言:javascript
运行
复制
@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没有激活。

代码语言:javascript
运行
复制
2017-12-14 16:25:19,374 [INFO ] SpringBootApp : The following profiles are active: jdbc,embedded,rmiEnabled

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

代码语言:javascript
运行
复制
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定义初始化。
  • 将它放置在一个完全不同的包中,具有不同的根,以确保它不会被任何错误的componentScan扫描。
  • 启用了整个spring框架上的调试日志,以查看在初始化这个方面之前记录了什么,但是没有任何东西接近根本原因。
  • 通过下面的代码自动读取rest控制器中的应用程序上下文和打印的bean定义名称列表。然而,方面没有初始化在部署,所以它不在那里; 用于(字符串s: context.getBeanDefinitionNames()) { System.out.println(s);}

我在java 7上使用的是aspectj 1.8.6和spring 4.3.2以及sprint-boot 1.4.0,任何帮助都将不胜感激。如果需要更多的细节,请告诉我;

EN

回答 2

Stack Overflow用户

发布于 2018-02-11 07:44:32

这对我起了作用:

代码语言:javascript
运行
复制
@Configuration
public class AopConfiguration {

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

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

Stack Overflow用户

发布于 2017-12-16 02:10:06

我在这里猜测,您确实成功地使用了aspectj,而不是spring (这两种非常不同的解决方案经常被混为一谈),但是,aspectj是一种完全独立于spring的技术,它不会考虑spring在配置文件选择方面的特定注释。spring的@Profile注释可能适用于spring,因为spring本身将为spring创建围绕spring的代理,但是使用本机aspectj则不是这样。

您需要在建议中进行运行时测试,以确定是否希望方面是活动的,可能会在afterPropertiesSet()中将布尔标志设置为afterPropertiesSet(),并在默认情况下保留标志false,以便如果方面在春季未配置,则不会运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47818300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档