• java:aocache 与Spring Aop兼容问题


    本文适用于所有AspectJ与Spring AOP混用的场景。

    Spring AOP 是基于动态代理的实现AOP,基于 JDK代理和CGLib代理实现运行时织入(runtime weaving)。

    Spring AOP的切面定义沿用了ASpectJ的注解体系,所以在Spring体系中注解定义切面的方式与ASpectJ完全兼容, 但如果一个项目中有Spring 切面定义又要使用aocache静态态织入(CTW)的情况下,就会存在冲突问题。

    如下面的示例,项目中定义了一个Spring AOP切面,拦截所有带@RestController注解的服务方法

    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    /**
     * 
     * 服务上下文切面
     *
     */
    @Aspect
    @Component
    public class ServiceContextAop {
        @Before("restControllerAspect()")
    	public void doServiceContextBefore(JoinPoint joinPoint) throws Throwable {
            // DO SOMETHING
        }
    	/**
    	 * 定义切入点为有注解{@link org.springframework.web.bind.annotation.RestController}下的所有类
    	 */
    	@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    	public void restControllerAspect() {
    	}
    
    }
    

    pom.xml中如下定义了aspectj-maven-plugin插件在项目编译时静态织入aocache定义的切面

    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.codehaus.mojogroupId>
    				<artifactId>aspectj-maven-pluginartifactId>
    				<version>1.10version>
    				<configuration>
    					<source>1.8source>
    					<target>1.8target>
    					<encoding>UTF-8encoding>
    					<complianceLevel>1.8complianceLevel>
    					<verbose>trueverbose>
    					<showWeaveInfo>trueshowWeaveInfo>
    					<aspectLibraries>
    						<aspectLibrary>
    							<groupId>com.gitee.l0kmgroupId>
    							<artifactId>aocacheartifactId>
    						aspectLibrary>
    					aspectLibraries>
    				configuration>
    				<executions>
    					<execution>
    						<goals>
    							<goal>compilegoal>
    						goals>
    					execution>
    				executions>
    			plugin>
    		plugins>
    	build>
    

    编译时不会有任何问题,但是在程序运行时,就会发现ServiceContextAop定义的切面没有起作用。

    因为aspectj-maven-plugin插件识别到了ServiceContextAop类上的@Aspect注解,将本该由Spring AOP管理的切面也执行了静态织入。如下为ServiceContextAop.class反编译显示的代码,可以看到ASpectJ在类中增加了额外代码。
    在这里插入图片描述

    为解决ASpectJ CTW模式与Spring AOP的共存问题,就要在aspectj-maven-plugin插件中使用 参数指定在执行静态织入时排除ServiceContextAop.java

    <build>
    	<plugins>
    		<plugin>
    			<groupId>org.codehaus.mojogroupId>
    			<artifactId>aspectj-maven-pluginartifactId>
    			<version>1.10version>
    			<configuration>
    				<source>1.8source>
    				<target>1.8target>
    				<encoding>UTF-8encoding>
    				<complianceLevel>1.8complianceLevel>
    				<verbose>trueverbose>
    				<showWeaveInfo>trueshowWeaveInfo>
    				<aspectLibraries>
    					<aspectLibrary>
    						<groupId>com.gitee.l0kmgroupId>
    						<artifactId>aocacheartifactId>
    					aspectLibrary>
    				aspectLibraries>
        			
                    <excludes>
    	                <exclude>**/ServiceContextAop.javaexclude>
                    excludes>
    			configuration>
    			<executions>
    				<execution>
    					<goals>
    						<goal>compilegoal>
    					goals>
    				execution>
    			executions>
    		plugin>
    	plugins>
    build>
    

    参考资料

    关于 参数说明参见

    《Using includes/excludes》

  • 相关阅读:
    Drive to APasS!使用明道云管理F1赛事
    springboot开启Redis缓存支持
    Emgu CV4图像处理之打开Tensorflow训练模型17(C#)
    学习CentOS7系统安装nginx环境,以及相关配置命令
    EasyCode介绍及自定义模板
    Linux 中的 cpp 命令及示例
    Go-zero框架学习+xorm+gorm配置
    SpringBoot+Mybaits搭建通用管理系统实例十一:数据缓存功能实现
    redis最佳实践
    JavaWeb篇_07——Tomcat组件介绍
  • 原文地址:https://blog.csdn.net/10km/article/details/140461912