`
lishiguang
  • 浏览: 192975 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

实现自己的AOP

AOP 
阅读更多

使用cglib配合Annotation   实现一个AOP

先看代码后解释:

public interface AOPInterface {
 public void BeforeMethod();
 public void AfterMethod();
}

上面的是AOP的接口,包含了方法执行前和执行后的方法

public class Caller implements MethodInterceptor {

 private AOPInterface Iaop;
 
 public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
  Object result = null;
  /**
   * 当Annotation在类上方的时候,应该判断superclass是否有Annotation
   * 因为cglib帮你创建出来的已经是动态继承了你的类,成了子类!!
   * 关键!!
   */
  if(obj.getClass().getSuperclass().isAnnotationPresent(InterceptorHandler.class)){
   this.Iaop.BeforeMethod();
   result = invokeMethod(obj,args,proxy); //方法在下面
   this.Iaop.AfterMethod();
   return result;
  }else{
   if(method.isAnnotationPresent(InterceptorHandler.class)){
    this.Iaop.BeforeMethod();
    result = invokeMethod(obj,args,proxy); //方法在下面
    this.Iaop.AfterMethod();
    return result;
   }else{
    return invokeMethod(obj,args,proxy);
   }
  }
 }

 private Object invokeMethod(Object obj,Object[] args,MethodProxy proxy) throws Throwable {
  return proxy.invokeSuper(obj, args);
 }

// get、set省略...
}

这个是cglib代理方法的调用类,为它加入了一个AOP接口的引用,使得方法调用前后可以灵活的改变

(有点类似于策略模式)

public class TestHandler implements AOPInterface {
 public void AfterMethod() {
  System.out.println("Good Bye!");
 }

 public void BeforeMethod() {
  System.out.println("Hello!");
 }

}

这个是真实的AOP处理类,实现了AOPInterface接口,只要实现了这个接口,就可以在AOP的时候调用

里面的方法 After和Before

@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD,ElementType.TYPE})
public @interface InterceptorHandler {
 public Class<?> handlerClass();
}

这个是注解的开发!可以看到注解保持到RUNTIME,就可以用反射取得,

可以标注的地方为方法上(METHOD)和类上(类、接口、枚举都是使用TYPE类型)

唯一的属性是,处理这个AOP的类型

public class AOPFactory {
 
 public Map<String,Class<?>> beansInfo;
 /**
  * 这个方法是通过配置取得Bean信息
  * 我在此处就省略,直接取得目标Bean,
  * 对真实扫描不懂可以看我的博客“取得包内的类”
  */
 public AOPFactory(){
  this.beansInfo = new HashMap<String, Class<?>>();
  this.beansInfo.put("TrueClass", TrueClass.class);
  this.beansInfo.put("TrueClass2", TrueClass2.class);
  this.beansInfo.put("TestHandler", TestHandler.class);
 }
 /**
  * 这个方法我也简化,直接使用手动装配
  */
 public Object getBean(String beanName) throws InstantiationException, IllegalAccessException{
  //取得Bean的类型
  Class<?> clazz = this.beansInfo.get(beanName);
  //装配AOP
  AOPInterface handler = (AOPInterface)(this.beansInfo.get("TestHandler").newInstance());
  Caller c = new Caller();
  c.setIaop(handler);
  //cglib代理创建者
  Enhancer eh = new Enhancer();
  eh.setSuperclass(clazz);
  eh.setCallback(c);
  //创建代理
  return eh.create();
 }
}

上面这个是AOP的工厂类,由于篇幅关系,我做了非常大的简化,自动扫描包,改为了手动装配

如果想要了解像Spring一样自动扫描包的功能,在我博客上也有,有兴趣可以看一下

public class TrueClass {
 @InterceptorHandler(handlerClass=TestHandler.class)
 public void meetMM(){
  System.out.println("Just Go Around With MM!");
 }
 public void afterMeetMM(){
  System.out.println("Go Home!");
 }
}

@InterceptorHandler(handlerClass=TestHandler.class)
public class TrueClass2 {
 public void BuySomeThing(){
  System.out.println("我就要这些,多少钱?");
 }
 public void NoMoney(){
  System.out.println("我忘带钱了");
 }
}

上面两个类,是真实的业务类,是用来测试的,TrueClass类只有方法上有注解,而TrueClass2

类上有注解,代表了这个类的所有方法都被cglib拦截

下面是测试方法(JUnit4)

@Test
 public void testAOP(){
  AOPFactory factory =  new AOPFactory();
  try {
   TrueClass tc = (TrueClass)factory.getBean("TrueClass");
   tc.meetMM();
   tc.afterMeetMM();
   
   TrueClass2 tc2 = (TrueClass2)factory.getBean("TrueClass2");
   tc2.BuySomeThing();
   tc2.NoMoney();
 
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

执行后输出的果是:

Hello!
Just Go Around With MM!
Good Bye!
Go Home!
Hello!
我就要这些,多少钱?
Good Bye!
Hello!
我忘带钱了
Good Bye!

可以看到我们注释上的方法都被拦截了,没有注释的就没有拦截(Go Home前后)

 

上面的方法要注意的地方再总结一下:

1)cglib方法代理方法的调用类(Caller)中 ,执行方法的函数不是invoke,而是invokeSuper

因为cglib动态继承了你的类,导致了invoke会不断执行Caller的方法,而不是代理类的

2)在判断类的上方是否有Annotation的时候

不是xxx.getClass.isAnnotationXXXXX()

而是xxx.getClass.getSuperClass.isAnnotationXXXXX()

原因也是cglib动态继承所造成的!

 

注:如果运行报错 请检查是否缺少asm jar包

 

 

 

感谢作者分享 转自:http://emavaj.blog.163.com/blog/static/133280557201003111711997/

分享到:
评论

相关推荐

    基于注解实现SpringAop

    基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    动态代理是实现AOP的一种常用技术,它允许在运行时创建代理对象,拦截对真实对象的调用,并在调用前后添加额外的行为。 在Java开发中,反射机制是实现动态代理的关键技术之一。反射提供了在运行时访问和操作类的...

    Xml配置实现AOP

    基于代理实现AOP切面编程 基于代理的AOP实现主要涉及到两种代理方式:JDK动态代理和CGLIB代理。Spring会根据目标对象是否实现了接口来选择合适的代理方式。 - **JDK动态代理**:如果目标对象实现了至少一个接口,...

    使用Spring的注解方式实现AOP的细节

    本篇文章将深入探讨如何通过Spring的注解方式实现AOP的细节。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切点(Pointcut)定义了哪些方法会被通知(Advice...

    用java自己实现的动态代理 AOP

    下面我们将深入探讨Java动态代理的原理以及如何实现AOP功能。 ### 一、Java动态代理原理 Java中的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。`Proxy`类用于...

    利用C#实现AOP常见的几种方法详解

    在C#中,实现AOP的方法多种多样,以下将详细介绍几种常见的实现方式。 1. **静态织入**: 静态织入是在编译时完成的,它通过编译器或者编译插件(如PostSharp)在目标类的代码中插入拦截逻辑。这种方式的优点是...

    Unity结合三导实现依赖注入跟AOP

    拦截器是实现AOP的核心,它在方法调用前后执行自定义逻辑。 3. 创建拦截器:通过继承`IInterceptor`接口或使用`Unity.Interception`库中的`InterceptionBehavior`抽象类,我们可以创建自定义拦截器。例如,创建一个...

    JavaEE spring自动实现AOP代理

    Spring 提供了两种方式来实现AOP代理:JDK动态代理和CGLIB代理。 1. **JDK动态代理**: - JDK动态代理基于Java的接口实现,适用于目标对象实现了接口的情况。Spring会为这个接口创建一个代理类,代理类在调用真实...

    C# 实现的AOP框架

    在C#中,实现AOP可以帮助开发者处理如日志记录、事务管理、性能度量等横切关注点,这些关注点通常会分散在应用程序的各个角落。C#实现的AOP框架可以通过动态代理、编译时织入或运行时织入等方式实现。 C#中常见的...

    Asp.net Core 3.1基于AspectCore实现AOP实现事务、缓存拦截器功能

    在net core2.2时,我当时就尝试过用autofac实现aop,但这次我不想用autofac,我用了一个更轻量级的框架,AspectCore。 用起来非常非常的简单,但一开始还是走了一点弯路,主要是网上都是net core3以下的教程,3以下...

    用Java动态代理实现AOP

    Java动态代理实现AOP Java动态代理是实现Aspect Oriented Programming(AOP)的重要手段。在Java中,动态代理可以通过java.lang.reflect InvocationHandler接口和java.lang.reflect.Proxy类来实现。AOP的主要思想...

    .net平台AOP的实现

    在.NET平台上实现AOP,我们可以借助于不同的库和技术,如PostSharp、Unity、Autofac等。下面我们将深入探讨.NET平台AOP的实现方法和应用。 首先,我们需要理解AOP的基本概念。AOP的核心是切面(Aspect),它封装了...

    Xml文件配置实现AOP通知

    通过Spring的XML配置,我们可以灵活地定义和实现AOP通知,包括前置、后置、返回后、异常后以及环绕通知。这使得我们可以将横切关注点与业务逻辑分离,提高代码的可维护性和复用性。Spring的AOP功能强大且易于使用,...

    模拟spring aop【一】基于jdk动态代理实现的aop

    本篇文章将探讨如何通过JDK动态代理实现Spring AOP的基础知识。 首先,我们要理解什么是JDK动态代理。在Java中,动态代理机制允许我们在运行时创建一个实现了特定接口的新类。这个新类的实例可以代理目标对象,执行...

    AOP使用CGLIB实现AOP功能

    Spring AOP实现方法之一:CGLIB 实现AOP功能

    注解实现AOP通知

    AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要特性,它提供了一种模块化和声明式的方式来处理...在实际项目中,结合使用这些注解可以实现各种复杂的切面功能,提升软件设计的质量和效率。

    注解方式实现AOP编程

    本篇将主要讨论如何通过注解方式来实现AOP编程。 首先,我们需要了解Spring中的核心注解。`@Aspect`是定义一个切面的注解,通常会定义在一个独立的类上。这个类将包含切点(Pointcut)和通知(Advice)。 切点是...

    C#自己实现AOP的事务操作

    C#作为.NET框架的主要编程语言,提供了强大的支持来实现AOP,特别是在处理事务管理方面。事务是数据库操作的核心概念,确保数据一致性并能够在异常情况下进行回滚。 C#实现AOP事务的关键在于利用特性(Attribute)...

    AOP的实现代码

    详细介绍了AOP的核心功能(拦截功能)在底层是如何实现的;介绍了两种实现AOP的动态代理:jdk动态代理和cglib动态代理,并详细描述了它们在代码层面的实现。附有必须的cglib.jar和asm.jar

    Spring Aop的简单实现

    在本项目中,我们将探讨如何通过配置文件实现Spring AOP,包括前置通知、后置通知以及拦截器的运用。 首先,我们需要理解Spring AOP的核心概念。切面(Aspect)是关注点的模块化,这些关注点定义了跨越多个对象的...

Global site tag (gtag.js) - Google Analytics