1. 程式人生 > >AOP如何對自定義註解進行切面程式設計

AOP如何對自定義註解進行切面程式設計

spring AOP需要的jar包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.7.3</version>
</dependency>



<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.7.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/cglib/cglib-nodep -->
<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib-nodep</artifactId>
   <version>2.1_3</version>
</dependency>
主要配置資訊:
設定切面代理
<aop:aspectj-autoproxy proxy-target-class="true" />
注入切面的類
<bean id="aspect" class="com.aspect.TestAnnoction" />
在service層做切面
<bean id="testAnnoctionService" class="com.service.TestAnnoctionService" />
說明我是在自定義的註解上做的切面
註解類程式碼:
package com.Annotion;


import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnoction {
String key() default "";
}
切面類程式碼:
package com.aspect;


import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;


import com.Annotion.MyAnnoction;


@Component
@Aspect
public class TestAnnoction {

//@Pointcut("execution(* com.service.TestAnnoction.testMyAnnoction(..))")
//    public void testMyAnnoction(){}

public TestAnnoction() {
System.out.println("我是一個構造器111");
}




//@Around(value = "@annotation(com.Annoction.MyAnnoction)")
//@Around(value = "testMyAnnoction()")
@Around(value = "@annotation(com.Annotion.MyAnnoction)")
public Object testMyAnnoction(ProceedingJoinPoint pj) throws Throwable{
System.out.println("========================");
Object target = pj.getTarget();
System.out.println(target.toString());
Class<?> cls = getTargetClass(target);
Method specificMethod = getSpecificMethod(pj, cls);
if (!Modifier.isPublic(specificMethod.getModifiers())) {
            return pj.proceed();//這是判斷是否執行真實的方法體
        }
MyAnnoction ma = specificMethod.getAnnotation(MyAnnoction.class);
String key = ma.key();
System.out.println("當前測試的key:" + key);
return new Object();

}

    /**
     * 獲取目標Class
     *
     * @param target
     * @return
     */
    private Class<?> getTargetClass(Object target) {
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
        if (targetClass == null) {
            targetClass = target.getClass();
        }
        return targetClass;
    }
    
    /**
     * 獲取指定方法
     *
     * @param pjp
     * @param targetClass
     * @return
     */
    private Method getSpecificMethod(ProceedingJoinPoint pjp, Class<?> targetClass) {
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
        specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
        return specificMethod;
    }
}
Service層使用
@MyAnnoction(key="1")
public void testMyAnnoction(){
System.out.println("是否開始執行我的資料1");
}

@MyAnnoction(key="0")
public void testMyAnnoction1(){
System.out.println("是否開始執行我的資料0");
}
Controller注入service使用
@Autowired
private TestAnnoction testAnnoctionService;
//開始呼叫
testAnnoctionService.testMyAnnoction();
//開始呼叫
testAnnoctionService.testMyAnnoction1();