Spring/AOPフレーム及び注釈を使用する

11554 ワード

1、エージェントを使ってログを追加するのも、最も原始的な方法に基づいている.
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class LoggingProxy {
    /*
     *    ,     
     */
    //       ,     
    private Icalculator target;
    //        
    public LoggingProxy(Icalculator target) {
        super();
        this.target = target;
    }
    //    .      
    public Icalculator getProxy() {
        Icalculator ica = null;
        //    
        //      : ClassLoader,      getClass()    
        ClassLoader cl = target.getClass().getClassLoader();
        
        //  class        ,            .class
        Class[] cla= new Class[] {Icalculator.class};
        //Class[] al = new Class[] {IJiSuanQi.class};//  
        
        //  
        InvocationHandler ih = new InvocationHandler() {
            @Override
            //  invoke             
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //            
                Object obj = null;
                System.out.println(method.getName()+"     ");
                try {
                    obj = method.invoke(target, args);
                }
                catch(Exception e) {
                    System.out.println("    : "+method.getName());
                }
                System.out.println(method.getName()+"     ");
                return obj;
            }
        };
        //      ,       jar 
        ica = (Icalculator)Proxy.newProxyInstance(cl, cla, ih);
        return ica;
    }
}
2,AOPフレームを使用する
設定ファイル
    <!--       class -->
    <bean id="cal" class="com.hanqi.Calculator">
    </bean>
    
    <!--     -->
    <bean id="la" class="com.hanqi.LoggingAspect">
    </bean>
    
    <!--   AOP -->
    <aop:config>
    <!--        ,        -->
    <!-- expression                 ,            *    -->
        <aop:pointcut expression="execution(* com.hanqi.Icalculator.*(int,int))" id="loggingpointcut"/>
        
        <!--         -->
        <aop:aspect ref="la">
            <!--       -->
            <aop:before method="beforeMethod" pointcut-ref="loggingpointcut"/>
            <aop:after method="afterMethod" pointcut="execution(* com.hanqi.Icalculator.cheng(int,int))"/>
            <aop:after-throwing method="exceptionMethod" pointcut-ref="loggingpointcut" throwing="ex"/>
            <aop:after-returning method="returnMethod" pointcut-ref="loggingpointcut" returning="obj"/>
        </aop:aspect>
        
    </aop:config>
断面クラスを定義する
import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

public class LoggingAspect {
    //   ,     
    public void beforeMethod(JoinPoint jp) {
        //     
        String str = jp.getSignature().getName();
        //        
        Object[] obj = jp.getArgs();
        System.out.println("    = "+str);
        System.out.println(Arrays.asList(obj));
        System.out.println("         ");
    }
    public void afterMethod(JoinPoint jp) {
        System.out.println("         ");
    }
    //    
    public void exceptionMethod(JoinPoint jp,Exception ex) {
        System.out.println("    "+ex);
    }
    
    //    
    public void returnMethod(JoinPoint jp,Object obj) {
        System.out.println("       : "+obj);
    }
}
3,注釈を使う方式(赤い部分が注釈)は、必ず返却値と、expression表現を記入してください.
import org.springframework.stereotype.Component;

@Component("cal")
public class Calculator implements Icalculator {
    ......
       
    ......
}
import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect @Component public class LoggingAspect {
    //   ,     
    @Before(value = "execution(* com.hanqi.Calculator.*(..))")
    public void beforeMethod(JoinPoint jp) {
        //     
        String str = jp.getSignature().getName();
        //        
        Object[] obj = jp.getArgs();
        System.out.println("    = "+str);
        System.out.println(Arrays.asList(obj));
        System.out.println("         ");
    }
    //    
    @After("execution(* com.hanqi.Calculator.*(..))")
    public void afterMethod(JoinPoint jp) {
        System.out.println("         ");
    }
    //    
    @AfterThrowing(pointcut="execution(* com.hanqi.Calculator.*(..))", throwing="ex")
    public void exceptionMethod(JoinPoint jp,Exception ex) {
        System.out.println("    "+ex);
    }
    
    //    
    @AfterReturning(pointcut="execution(* com.hanqi.Calculator.*(..))", returning="obj")
    public void returnMethod(JoinPoint jp,Object obj) {
        System.out.println("       : "+obj);
    }
}
 コメントの設定ファイル
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">

<!--         -->
<!--     -->
<context:component-scan base-package="com.hanqi"></context:component-scan>
<!--   AOP   -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>