`
min4450
  • 浏览: 13203 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

AOP 的一些实现方法

 
阅读更多
前段时间去面试,被问到了AOP的原理,当时回答是通过代理,还自信满满的。原来还是存在其他的一些方法的。趁这段时间,离职之际冲冲电,稍微挖一下。


package demo.aop;

public interface ActionI {
	public void doSth();
}



package demo.aop;

public class ActionImpl implements ActionI {

	@Override
	public void doSth() {
		System.out.println("doing sth");
	}

}



1.通过装饰器方法
package demo.aop;

public class ActionDecorator implements ActionI {
	private ActionI action;

	public ActionDecorator(ActionI action) {
		this.action = action;
	}

	@Override
	public void doSth() {
		System.out.println("doSth invoke start");
		action.doSth();
		System.out.println("doSth invoke end");
	}

	public static void main(String[] args) {
		ActionI action = new ActionDecorator(new ActionImpl());
		action.doSth();

	}
}


输出:
doSth invoke start
doing sth
doSth invoke end


使用装饰器的时候,如果要切入多个方法的时候,装饰器内就需要手懂编写同样多个方法。这种方法是显然是不够动态和灵活的。

2.使用Proxy代理

package demo.aop;

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

public class ActionInvocationHandler implements InvocationHandler {
	
	private ActionI action;
	
	public ActionInvocationHandler(ActionI action){
		this.action = action;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Log.info(method.getName()+" start");
		method.invoke(action, args);
		Log.info(method.getName()+" end");
		return null;
	}
	
	
	public static void main(String[] args){
		ActionI action = (ActionI)Proxy.newProxyInstance(ActionI.class.getClassLoader(), new Class[] { ActionI.class },
				new ActionInvocationHandler(new ActionImpl()));
		action.doSth();
	}
	
}



输出
doSth start
doing sth
doSth end

不足之处在于:代理是面向接口的,代理的对象必须是对一个接口的实现。代理是通过反射机制实现的,效率不高。

相较以上两种方法,改变java方法的更直接的方法是修改字节码
Java 规范详细说明了 class 文件的格式,直接编辑字节码确实可以改变 Java 类的行为。
3.hook
启动时往 Java 虚拟机中挂上一个用户定义的 hook 程序,可以在装入特定类的时候改变特定类的字节码,从而改变该类的行为。但是其缺点也是明显的:

    Instrument 包是在整个虚拟机上挂了一个钩子程序,每次装入一个新类的时候,都必须执行一遍这段程序,即使这个类不需要改变。
    直接改变字节码事实上类似于直接改写 class 文件,无论是调用 ClassFileTransformer. transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer),还是 Instrument.redefineClasses(ClassDefinition[] definitions),都必须提供新 Java 类的字节码。也就是说,同直接改写 class 文件一样,使用 Instrument 也必须了解想改造的方法相对类首部的偏移量,才能在适当的位置上插入新的代码。

尽管 Instrument 可以改造类,但事实上,Instrument 更适用于监控和控制虚拟机的行为。

4.asm
Java 字节码操控框架,能动态生成类或者增强既有类的功能。

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Spring  AOP实现方法大全

    【Spring AOP实现方法大全】 在Spring框架中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种强大的设计模式,它允许我们在不修改业务代码的情况下,插入额外的功能,比如日志记录、事务管理等。在...

    springboot+aspect实现springaop拦截指定方法.zip

    7. **示例中的`boot-aspect`项目**:这个文件名可能指的是项目的一个模块或目录,它包含了SpringBoot应用的AOP实现。在这个模块中,我们可以找到配置文件(如`application.yml`或`application.properties`)、Spring...

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

    在使用反射实现AOP动态代理时,我们也需要注意一些问题。例如,由于代理类是在运行时动态创建的,这可能会影响程序的性能,特别是在频繁调用代理方法的情况下。因此,在实际开发中,需要根据应用场景的性能要求和...

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

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

    AOP的实现机制.

    二、AOP实现方式 1. 静态代理:通过Java反射API或者自定义接口实现,缺点是需要为每个目标类手动创建代理类。 2. 动态代理:Java提供两种动态代理方式,JDK动态代理和CGLIB代理。 - JDK动态代理:基于接口实现,...

    Java利用spring aop进行监测方法执行耗时

    代码实现简单,易于维护:使用 Spring AOP 可以将耗时监测的逻辑与业务逻辑进行解耦,避免业务逻辑代码的冗余和代码维护难度的提高。 2. 安全性高:使用 Spring AOP 进行方法耗时监测,可以在不修改业务逻辑代码的...

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

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

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

    在Spring AOP中,`Proxy`类会根据目标对象的接口生成一个代理类,这个代理类会实现目标对象的所有接口,并在每个方法调用前后插入相应的通知。`InvocationHandler`接口定义了一个`invoke`方法,当调用代理对象的方法...

    初探spring aop内部实现 java

    本篇文章将深入探讨Spring AOP的内部实现,以及如何通过源代码理解其DataSource实现和FactoryBean模式。 首先,让我们了解AOP的基本概念。AOP的核心思想是“切面”,它封装了特定的关注点,如日志记录、事务管理、...

    .net平台AOP的实现

    下面我们将深入探讨.NET平台AOP的实现方法和应用。 首先,我们需要理解AOP的基本概念。AOP的核心是切面(Aspect),它封装了横切关注点,即那些影响多个类或操作的代码。切点(Join Point)是指程序执行过程中的特...

    spring aop切面拦截指定类和方法实现流程日志跟踪

    本节将详细介绍如何使用Spring AOP实现流程日志跟踪,主要关注于如何通过AOP拦截特定的类和方法来进行日志记录。 ##### 3.1 配置Spring AOP 在Spring配置文件中定义切面和切入点表达式是非常关键的一步。一般来说...

    AOP的实现机制.pdf

    Spring AOP是Java环境中最广泛使用的AOP实现,它支持基于注解和XML配置的切面定义。通过`@Aspect`注解,我们可以创建切面类,使用`@Before`, `@After`, `@Around`等注解定义通知,并使用`@Pointcut`定义切入点。 ...

    Spring AOP实现机制

    - 代理对象在调用实际方法前后,会插入相应的通知代码,从而实现AOP功能。 - **CGLIB代理**: - 如果目标对象没有实现任何接口,Spring会使用CGLIB库创建一个目标对象的子类,并在子类中插入通知代码。 - CGLIB...

    AOP的实现机制

    AOP实现机制有多种,主要包括静态AOP、动态代理、动态字节码生成、自定义类加载器和字节码转换等。 1. 静态织入:在编译期通过修改源代码或字节码实现AOP。这种方式对系统性能无影响,但灵活性不够。 2. 动态代理...

    Spring Aop的简单实现

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

    spring源代码分析:aop的实现

    Spring的AOP代理(无论是JDK还是CGLIB)都会实现这个接口,并在intercept()方法中插入通知逻辑。 此外,Spring还提供了基于注解的AOP支持,如@Aspect、@Before、@After等,这使得AOP的使用更加便捷。在编译时,...

    .net中attribute实现方法调用拦截(就是aop)

    在提供的压缩包文件"aop实现"中,可能包含了具体的代码示例和文章,详细讲解了如何使用Attribute实现AOP。通过学习这些资料,你可以更深入地理解Attribute的高级应用,以及如何在.NET环境中实现方法调用的拦截。

    AOP使用CGLIB实现AOP功能

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

    AOP方式实现的redis分布式锁

    redis分布式锁的实现: ... 3、只需要在方法上声明@DistributedLock(可以是controller的方法也可以是service的公共方法)即可实现锁功能。 4、支持在@DistributedLock上动态传参,减少锁的颗粒度。

Global site tag (gtag.js) - Google Analytics