java注解处理

1.自定义注解类型
 
package com.yc.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 给方法添加日志处理
 * @author jp
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyLog {

    Class<?> value();

}
 
2.业务处理
package com.yc.annotation;
/**
 * 计算器业务处理接口
 * @author jp
 *
 */
public interface Calculator {
    
    int add(int num01, int num02);//加法操作
    
    int divid(int num01, int num02);//除法操作
}

package com.yc.annotation.impl;

import com.yc.annotation.Calculator;
import com.yc.annotation.MyLog;
/**
 * 计算器业务处理实现类
 * @author jp
 *
 */
public class CalculatorImpl implements Calculator {

    @MyLog(CalculatorLogging.class)
    public int add(int num01, int num02) {
        int result = num01 + num02;
        System.out.println(num01 + " + " + num02 + " = " + result);
        return result;
    }

    public int divid(int num01, int num02) {
        int result = num01 / num02;
        System.out.println(num01 + " / " + num02 + " = " + result);
        return result;
    }
}


 
3.日志处理
package com.yc.annotation;

/**
 * 日志处理接口
 * @author jp
 */
public interface ILogging {
    public void beginMethod(String methodName, Object...params); //前置处理日志
    
    public void afterMethod(String methodName, Object result);//后置处理日志
}

package com.yc.annotation.impl;

import java.util.Arrays;

import com.yc.annotation.ILogging;

/**
 * 日志处理实现类
 * @author jp
 */
public class CalculatorLogging implements ILogging{
    
    public void beginMethod(String methodName, Object...params){
        System.out.println(methodName + "开始计算,计算数据是:" + Arrays.toString(params));
    }
    
    public void afterMethod(String methodName, Object result){
        System.out.println(methodName + "计算完成,计算结果是:" + result);
    }
}

 
4.代理注解解析处理类 
package com.yc.annotation.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.yc.annotation.Calculator;
import com.yc.annotation.ILogging;
import com.yc.annotation.MyLog;
/**
 * 计算器处理的动态代理对象
 * @author jp
 */
public class ProxyCalculator {

    /**
     * @param c  具体要执行处理的实现类的接口类型
     * @return   代理对象
     */
    public Calculator getInstance(final Calculator c) {
        ClassLoader loader = c.getClass().getClassLoader();
        Class<?>[] interfaces = c.getClass().getInterfaces();
        InvocationHandler h = new InvocationHandler() {
            
            /* 代理对象回调处理函数
             * proxy代理对象 
             * method代理执行的方法 
             * args执行方法的参数
             */
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Method m = c.getClass().getMethod(method.getName(), method.getParameterTypes()); //取到具体执行的方法类对象
                Object result = null;
                if (m.isAnnotationPresent(MyLog.class)) { //判断方法是否被注解
                    MyLog ml = m.getAnnotation(MyLog.class);  //取到注解对象
                    ILogging cl = (ILogging) ml.value().newInstance(); //取到注解对象的参数值
                    cl.beginMethod(method.getName(), args); //前置处理日志
                    result = method.invoke(c, args);//执行方法
                    cl.afterMethod(method.getName(), result);//后轩算是日志
                } else {
                    result = method.invoke(c, args); //执行方法
                }
                return result;
            }
        };

        return (Calculator) Proxy.newProxyInstance(loader, interfaces, h); //创建代理对象
    }
}
 
5.测试处理结果
 package com.yc.annotation;

import static org.junit.Assert.*;

import org.junit.Test;

import com.yc.annotation.impl.CalculatorImpl;
import com.yc.annotation.impl.ProxyCalculator;

public class CalculatorTest {
    @Test
    public void testMethodAnnot() throws InstantiationException, IllegalAccessException {
        Calculator c = new ProxyCalculator().getInstance(new CalculatorImpl());
        int result = c.add(12, 23);  //加了日志注解的测试
        assertEquals(35, result);
        System.out.println("=========================");
        c.divid(4, 2); //没有加日志注解的测试
        assertEquals(2, result);
    }
}

结果:
add开始计算,计算数据是:[12, 23]
12 + 23 = 35
add计算完成,计算结果是:35
=========================
4 / 2 = 2 
原文地址:https://www.cnblogs.com/huozf/p/6234912.html