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.业务处理
3.日志处理
4.代理注解解析处理类
5.测试处理结果
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; } }
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); } }
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