`
king_tt
  • 浏览: 2233429 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Spring aop利用jdk的InvocationHandler产生动态代理

阅读更多

笔记之用……

 

首先有一个接口UserService

 

package com.spring.test;

import org.springframework.stereotype.Component;

@Component
public interface UserService {
	
	public void createUser();
	
	public void deleteUser();
	
	public void updateUser(int id);

}


UserDao实现UserService

 

 

package com.spring.test;

import org.springframework.stereotype.Component;

@Component
public class UserDao implements UserService {

	public void createUser() {
		System.out.println("user saved...");

	}
	
	public void deleteUser(){
		System.out.println("delete user...");
	}
	
	public void updateUser(int id){
		System.out.println("update user...");
	}

}



 

想要在这些方法执行的时候加一些业务逻辑,如公共日志或者计算方法执行前后的时间等,将代码以切面的形式切入到方法中,此时可以用动态代理来实现,

aop的动态代理底层是用jdk的动态代理实现的proxy和InvocationHandler,需实现java.lang.reflect.InvocationHandler

首先定义一个LogInteceptor来实现InvocationHandler:

 

package com.spring.log;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;

/*****************
 * 日志类
 * 
 * @author Administrator
 * 
 */
public class LogInteceptor implements InvocationHandler{

	private Object target;//被代理的对象
	
	public Object getTarget() {
		return target;
	}

	public void setTarget(Object target) {
		this.target = target;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		beforeMethod(method);//在方法执行前所要执行的业务逻辑
		long starttime=System.currentTimeMillis();
		method.invoke(target, args);
		long result=System.currentTimeMillis()-starttime;
		System.out.println("执行时间为:"+result+"毫秒");
		afterMethod(method);//在方法执行后所要执行的业务逻辑
		return null;
	}
	
	public void beforeMethod(Method m){
		System.out.println(m.getName()+"执行before....");
	}
	
	public void afterMethod(Method m){
		System.out.println(m.getName()+"执行after...");
	}

}


然后用JUnit来进行测试

 

 

package com.junit.test;

import java.lang.reflect.Proxy;

import com.spring.log.LogInteceptor;
import com.spring.test.UserDao;
import com.spring.test.UserService;


public class Test {
	
	
	@org.junit.Test
	public void testProxy(){
		
		UserDao userDao=new UserDao();//被代理的对象
		LogInteceptor logInteceptor=new LogInteceptor();//获取日志的InvocationHandler
		logInteceptor.setTarget(userDao);//把被代理的对象设为userDao
		
		//设置代理对象,参数1:被代理对象的classloader,参数2:被代理对象所实现的接口(该对象必须要实现接口,不然无法产生代理),参数3:指定处理的InvocationHandler
		UserService userService=(UserService)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), new Class[]{UserService.class}, logInteceptor);
		userService.createUser();//执行方法
		userService.deleteUser();//执行方法
		userService.updateUser(1001);//执行方法
	}

}

 

 

执行结果:

createUser执行before....
user saved...
---执行时间为:0毫秒
createUser执行after...
deleteUser执行before....
delete user...
---执行时间为:0毫秒
deleteUser执行after...
updateUser执行before....
update user...
---执行时间为:0毫秒
updateUser执行after...

 

 

接下来来点实际的..........................

 

定义一个LogInterceptor,让dao里的方法在执行的前后执行某些特定的方法

 

package com.spring.log;

public class LogInterceptor {
	
	public void beforeMethod(){
		System.out.println("方法执行前执行");
	}
	
	public void afterMethod(){
		System.out.println("方法执行后执行");
	}

}


定义的beforeMethod和afterMethod在applicationContext.xml里用aop配置

 

 

 

<bean id="mylog" class="com.spring.log.LogInterceptor"></bean>
	<aop:config>
		<aop:aspect id="log" ref="mylog">
			<aop:pointcut expression="execution (* com.spring.test.*.*(..))" id="point" /><!--切入点-->
			<aop:before method="beforeMethod"  pointcut-ref="point"/><!-- 定义方法before前执行自己定义的beforeMethod -->
			<aop:after method="afterMethod" pointcut-ref="point"/><!-- 定义方法after后执行自己定义的afterMethod -->
		</aop:aspect>
	</aop:config>

 

当然还可以配置

 

<aop:around method=""/>
<aop:after-returning method=""/>
<aop:after-throwing method=""/>


最后用JUnit测试:

 

 

@org.junit.Test
	public void Test(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService service = (UserService) ctx.getBean("userDao");
		service.createUser();
	}


执行结果:

 

方法执行前执行
user saved...
方法执行后执行

 

 

如果要获取执行的类和方法,可以接一个JoinPoint参数,用来获取执行的方法名

 

package com.spring.log;

import org.aspectj.lang.JoinPoint;

public class LogInterceptor {
	
	public void beforeMethod(JoinPoint point){
		System.out.println("方法执行前执行");
		//System.out.println(point.getTarget());//获取类com.spring.test.UserDao@15e0873
		//System.out.println(point.getSignature().getName());//获取方法名
		System.out.println(point.getTarget()+"类的"+point.getSignature().getName()+"方法执行!!!");
	}
	
	public void afterMethod(JoinPoint point){
		System.out.println("方法执行后执行");
		System.out.println(point.getTarget()+"类的"+point.getSignature().getName()+"方法执行完毕!!!");
	}

}



 



分享到:
评论

相关推荐

    spring之AOP(动态代理)

    在Spring中,AOP主要通过两种动态代理技术实现:JDK动态代理和CGLIB动态代理。 首先,让我们详细了解一下JDK动态代理。JDK动态代理基于Java的接口实现,它适用于目标对象实现了至少一个接口的情况。在运行时,JDK...

    JDK动态代理 spring aop 的原理

    Spring AOP(面向切面编程)则是一种流行的应用框架,它利用动态代理来实现对业务代码的切面增强,如日志、事务管理等。现在让我们深入探讨JDK动态代理和Spring AOP的原理。 首先,JDK动态代理基于Java的反射机制,...

    spring_aop之JDK的动态代理

    本文将深入探讨Spring AOP中的JDK动态代理机制。 首先,我们要理解什么是动态代理。动态代理是在运行时创建一个实现了一组给定接口的代理类,这个代理类可以拦截并处理方法调用,从而实现一些额外的功能。JDK的动态...

    Spring框架中JDK动态代理和cglib动态代理

    Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...

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

    Spring AOP支持不同的代理策略,包括JDK动态代理和CGLIB代理。如果被代理的类没有实现接口,Spring AOP会采用CGLIB来生成代理对象。CGLIB(Code Generation Library)是一个开源的代码生成库,它允许运行时在内存中...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态代理。 JDK 动态代理是基于接口的,它要求被代理的目标对象必须实现至少一个接口。Spring 使用 `java.lang.reflect.Proxy`...

    Spring Aop的底层实现技术 --- Jdk动态代理原理

    Spring AOP 的底层实现技术 --- Jdk 动态代理原理 JDK 动态代理是 Spring AOP 的底层实现技术,允许开发者在运行期创建接口的代理实例。在 JDK 1.3 以后,JDK 动态代理技术提供了实现 AOP 的绝好底层技术。JDK 动态...

    从JDK动态代理到spring AOP

    本篇将详细探讨JDK动态代理和Spring AOP,以及它们在实际应用中的作用。 首先,JDK动态代理是Java提供的一种在运行时创建代理对象的技术。它允许我们在不修改原有类的基础上,为已有接口添加额外的功能。动态代理的...

    代理模式,JDK动态代理,SpringAOP来龙去脉

    在Java中,我们可以使用JDK的动态代理或者Spring AOP来实现代理模式。 JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类是生成代理对象的工厂,而...

    spring jdk动态代理

    Spring AOP中的JDK动态代理与上述示例类似,只是Spring会自动处理代理对象的创建和`InvocationHandler`的设置。Spring通过`DefaultAopProxyFactory`和`JdkDynamicAopProxy`类来实现这一过程。在配置了AOP代理后,当...

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

    在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者定义“切面”,...通过理解JDK动态代理的工作原理和Spring AOP的相关概念,我们可以更好地利用这一强大功能,提升应用程序的可维护性和灵活性。

    springAop默认代理方式.zip

    2. **动态代理**:Spring AOP 的默认代理方式是动态代理,它包括JDK动态代理和CGLIB代理。当目标对象实现了至少一个接口时,Spring将使用JDK的动态代理机制。JDK动态代理通过实现InvocationHandler接口,并在运行时...

    Java动态代理(Spring Aop原理)

    Spring AOP提供了两种代理方式:JDK动态代理和CGLIB代理。JDK动态代理用于目标对象实现接口的情况,而CGLIB代理则用于目标对象没有实现接口的情况。Spring默认使用JDK动态代理,但如果目标对象没有实现接口,它会...

    Spring AOP的静态代理和动态代理,转移到调用处理器一个集中的方法中处理.docx

    【Spring AOP的静态代理和动态代理】 在软件开发中,代理模式是一种常见的设计模式,它允许我们在不修改原有对象的基础上,对对象的行为进行增强。代理模式的核心思想是通过代理对象来控制对原始对象(也称为委托...

    Spring框架+SpringAOP动态代理

    ### Spring框架+SpringAOP动态代理 #### 一、Spring AOP 动态代理概述 在探讨Spring AOP(Aspect-Oriented Programming,面向切面编程)中的动态代理之前,我们首先简要回顾一下AOP的基本概念。面向切面编程是一种...

    [#0x0042] Spring AOP学习(二):动态代理

    在Spring AOP的学习中,动态代理是一个至关重要的概念。...无论是JDK动态代理还是CGLIB代理,都是Spring框架实现AOP的重要手段,了解并掌握它们的原理和使用,对于深入理解和使用Spring AOP至关重要。

    day39-Spring 03-JDK的动态代理

    本文将深入探讨"day39-Spring 03-JDK的动态代理"这一主题,该主题主要关注Spring框架如何利用JDK的动态代理机制实现AOP(面向切面编程)。 首先,我们需要理解什么是动态代理。在Java中,动态代理是一种在运行时...

    从JDK动态代理看Spring之AOP实现

    本文将深入探讨Spring是如何通过JDK的动态代理来实现AOP的。 首先,我们要理解JDK动态代理的基本原理。在Java中,动态代理主要由`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口组成。...

    浅谈JDK动态代理与CGLIB代理去区别

    在"通过Configuration文件实现AOP.docx"文档中,可能会详细讲述如何在Spring配置文件中配置AOP代理,包括如何选择使用JDK动态代理还是CGLIB。 总结来说,JDK动态代理简单且高效,适合接口驱动的设计,而CGLIB适用于...

    spring-demo16-JDK动态代理.zip

    在Spring框架中,AOP代理可以自动利用JDK动态代理或CGLIB(当目标类没有实现接口时)。Spring AOP提供了更高级别的抽象,让我们可以在不直接操作`InvocationHandler`的情况下实现相同的目标。通过配置或注解,我们...

Global site tag (gtag.js) - Google Analytics