Java使用注解和动态代理实现方法调用时的日志记录示例
2017-10-27 10:09
1286 查看
1.定义一个注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogTag {
String level() default "info";
}
2.定义一个接口
public interface ITest {
void excuteBusiness();
}
3.定义一个代理类
/**
* 代理类
* @author chenshuai
* @version 1.0
*
*/
public class ProxyBean implements InvocationHandler {
private Object o;
/**
* @return the o
*/
private Object getO() {
return o;
}
/**
* @param o the o to set
*/
private void setO(Object o) {
this.o = o;
}
/**
* 创建代理
* @param obj
* @return
*/
public static <T> T createProxy(T obj) {
ProxyBean tem = new ProxyBean();
tem.setO(obj);
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), tem);
}
/*
* (non-Javadoc)
*
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//从实际的类对象中查找到所调用的具体方法,用来检测实际类的方法上的注解
//否则需要把注解加载接口的方法上
Method[] methods = o.getClass().getMethods();
List<Class<?>> types = new ArrayList<Class<?>>();
Method mm = null;
//通过反射查找方法
if (args == null || args.length == 0) {
mm = o.getClass().getMethod(method.getName(), null);
} else {
for (Object oo : args) {
types.add(oo.getClass());
}
mm = o.getClass().getMethod(method.getName(), (Class<?>[]) types.toArray());
}
System.out.println("代理启动");
//检查注解类型
Annotation[] annos = mm.getAnnotations();
for (Annotation anno : annos) {
if (anno instanceof LogTag) {
LogTag tem = (LogTag) anno;
System.out.println("探测到了LogTag注解,并且发现注解的level值为:" + tem.level());
}
}
//调用具体的方法,执行业务逻辑
method.invoke(o, args);
System.out.println("代理结束");
return null;
}
}
4.定义一个入口测试类
public class TestBean implements ITest {
@LogTag(level = "warn")
public void excuteBusiness() {
System.out.println("启动业务处理");
}
public static void main(String[] args) {
ITest a = new TestBean();
ITest proxy = ProxyBean.createProxy(a);
proxy.excuteBusiness();
}
}
运行结果
知识点:
1.Java动态代理:需要注意的是Java的动态代理要求被代理类必须继承自接口。
2.注解:注意@Retention和@Target两个注解的使用方法。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogTag {
String level() default "info";
}
2.定义一个接口
public interface ITest {
void excuteBusiness();
}
3.定义一个代理类
/**
* 代理类
* @author chenshuai
* @version 1.0
*
*/
public class ProxyBean implements InvocationHandler {
private Object o;
/**
* @return the o
*/
private Object getO() {
return o;
}
/**
* @param o the o to set
*/
private void setO(Object o) {
this.o = o;
}
/**
* 创建代理
* @param obj
* @return
*/
public static <T> T createProxy(T obj) {
ProxyBean tem = new ProxyBean();
tem.setO(obj);
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), tem);
}
/*
* (non-Javadoc)
*
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//从实际的类对象中查找到所调用的具体方法,用来检测实际类的方法上的注解
//否则需要把注解加载接口的方法上
Method[] methods = o.getClass().getMethods();
List<Class<?>> types = new ArrayList<Class<?>>();
Method mm = null;
//通过反射查找方法
if (args == null || args.length == 0) {
mm = o.getClass().getMethod(method.getName(), null);
} else {
for (Object oo : args) {
types.add(oo.getClass());
}
mm = o.getClass().getMethod(method.getName(), (Class<?>[]) types.toArray());
}
System.out.println("代理启动");
//检查注解类型
Annotation[] annos = mm.getAnnotations();
for (Annotation anno : annos) {
if (anno instanceof LogTag) {
LogTag tem = (LogTag) anno;
System.out.println("探测到了LogTag注解,并且发现注解的level值为:" + tem.level());
}
}
//调用具体的方法,执行业务逻辑
method.invoke(o, args);
System.out.println("代理结束");
return null;
}
}
4.定义一个入口测试类
public class TestBean implements ITest {
@LogTag(level = "warn")
public void excuteBusiness() {
System.out.println("启动业务处理");
}
public static void main(String[] args) {
ITest a = new TestBean();
ITest proxy = ProxyBean.createProxy(a);
proxy.excuteBusiness();
}
}
运行结果
知识点:
1.Java动态代理:需要注意的是Java的动态代理要求被代理类必须继承自接口。
2.注解:注意@Retention和@Target两个注解的使用方法。
相关文章推荐
- java使用动态代理来实现AOP(日志记录)
- java动态代理详解,并用动态代理和注解实现日志记录功能
- java使用动态代理来实现AOP(日志记录)的实例代码
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- java使用动态代理来实现AOP(日志记录)的实例代码
- java 动态代理aop 实现日志记录
- java动态代理对象实现日志的拦截(annotation自定义注解方式)
- Java JDK 动态代理的使用方法示例
- 系统性能监控系列1:使用JAVA动态代理实现非侵入式的性能测量方法
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
- CGLIB动态代理应用-java使用记录操作日志
- JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
- JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)
- Java动态代理实现模拟RMI远程方法调用
- 使用Java动态代理实现AOP
- 使用动态代理记录方法执行的时间
- 使用JAVA中的动态代理实现数据库连接池
- 使用JAVA中的动态代理实现数据库连接池