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

java注解处理的更多相关文章

  1. Java注解

    Java注解其实是代码里的特殊标记,使用其他工具可以对其进行处理.注解是一种元数据,起到了描述.配置的作用,生成文档,所有的注解都隐式地扩展自java.lang.annotation.Annotati ...

  2. 19.Java 注解

    19.Java注解 1.Java内置注解----注解代码 @Deprecated                                    //不推荐使用的过时方法 @Deprecated ...

  3. Java注解入门

    注解的分类   按运行机制分:   源码注解:只在源码中存在,编译后不存在 编译时注解:源码和编译后的class文件都存在(如@Override,@Deprecated,@SuppressWarnin ...

  4. java注解(Annotation)解析

    注解(Annotation)在java中应用非常广泛.它既能帮助我们在编码中减少错误,(比如最常见的Override注解),还可以帮助我们减少各种xml文件的配置,比如定义AOP切面用@AspectJ ...

  5. JAVA 注解的几大作用及使用方法详解

    JAVA 注解的几大作用及使用方法详解 (2013-01-22 15:13:04) 转载▼ 标签: java 注解 杂谈 分类: Java java 注解,从名字上看是注释,解释.但功能却不仅仅是注释 ...

  6. attilax.java 注解的本质and 使用最佳实践(3)O7

    attilax.java 注解的本质and 使用最佳实践(3)O7 1. 定义pojo 1 2. 建立注解By eclipse tps 1 3. 注解参数的可支持数据类型: 2 4. 注解处理器 2 ...

  7. paip.java 注解的详细使用代码

    paip.java 注解的详细使用代码 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...

  8. JAVA 注解的几大作用及使用方法详解【转】

    java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...

  9. 框架基础——全面解析Java注解

    为什么学习注解? 学习注解有什么好处? 学完能做什么? 答:1. 能够读懂别人写的代码,特别是框架相关的代码: 2. 让编程更加简洁,代码更加清晰: 3. 让别人高看一眼. spring.mybati ...

  10. Java注解配置

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.包含在 java.lang.annota ...

随机推荐

  1. System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本问题

    出错的原因: 1.虽然报的是需要安装客户端8.1.7及以上版本,实际是由于.NET账户没有访问Oracle\bin文件夹的权限 2.在 Windows Server 2003/2008 或Window ...

  2. Ubuntu学习总结-10 XManager

    最近接触到一个很有意思的实验,在这里与大家分享,实验目标在Window显示UBuntu程序. 1 测试环境: Windows8的IP地址 : 192.168.7.126 UBuntu16的IP地址 : ...

  3. BZOJ3932: [CQOI2015]任务查询系统

    传送门 真不知道我没学主席树之前是有什么勇气说自己高级数据结构以及学的七七八八了. 这道题应该也是算是主席树的经典运用. 刚开始脑抽了,想把(S,E,P)的处理直接在线用树状数组xjb搞搞算了.写完后 ...

  4. centos6.5 卸载php

    1.删除php,删除之前需要查看php依赖包,使用 rpm -qa|grep php [root@localhost ~]# rpm -qa |grep phpphp55w-mysql-5.5.38- ...

  5. ReportServices如何在一页中将报表分成两列显示

    创建两个数据集 DataSet1    DataSet2 DataSet1 SELECT   TOP                    (SELECT   (COUNT(*) + 1) / 2 A ...

  6. Spring特性--DI

    DI:Dependency Injection(依赖注入),通俗的讲就是一种通过xml配置文件,为交给sping容器的对象初始化参数.又称做控制反转:Inversion of Control(IoC) ...

  7. linux 主机名

    查看主机名命令:# uname -n csdba #hostname csdba 1.通过hostname命令.命令格式:hostname newhostname 此命令的作用是暂时的修改linux的 ...

  8. Node.js之路【第一篇】初识Node.js

    什么是Node.js 1.Node.js就是运行在服务端的JavaScrip. 2.Node.js是一个基于Chrome JavaScrip运行时简历的一个平台. 3.Node.js是一个非阻塞I/O ...

  9. ASP.MVC 基于AuthorizeAttribute权限设计案例

    ASP.MVC上实现权限控制的方法很多,比如使用AuthorizeAttribute这个特性 1.创建自定义特性用于权限验证 public class AuthorizeDiy : Authorize ...

  10. 解决Myeclipse PermGen space问题

    myeclipse配置web服务器配置 Window—Preferences—Myeclipse—Servers—tomcat JDK的Optional Java VM arguments配置为:-X ...