`
暮雨风吹
  • 浏览: 15976 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Spring动态代理实现

阅读更多

今天是学习Spring的第二天,看到了AOP,即AspectOrientedProgramming 面向切面编程,

JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。而Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例。下面我就用一个实例演示面向切面编程中动态代理的过程。

首先把需要的类引入进来

User类:

 

package com.spring.model;

public class User {

	private String userName;
	private String password;
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}

 

 

接口UserDao:

package com.spring.dao;

import com.spring.model.User;

public interface UserDao {

	public void save(User u);
	
	public void delete();
}


UserDaoImpl:

package com.spring.dao.impl;

import com.spring.dao.UserDao;
import com.spring.model.User;

public class UserDaoImpl implements UserDao{

	public void save(User u) {

		System.out.println("user saved !");
	}
	
	public void delete()
	{
		System.out.println("delete ok !");
	}

}


好了,下面我们要做的事就是写出一个UserDaoImpl类的动态代理类,这个代理类实现的功能是在调用UserDaoImpl类方法的时候提示该方法已经开始执行的语句。代理类LogInterceptor,他实现了InvocationHandler接口

package com.spring.aop;

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

public class LogInterceptor implements InvocationHandler {

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

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

	public void beforeMethod(Method m)
	{
		System.out.println(m.getName()+" start !");
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)  
			throws Throwable {
	             beforeMethod(method);
		method.invoke(target, args);
		return null;
	}
}

 

在接口方法invoke(Object proxy, Methodmethod, Object[] args)里,将目标类实例传给method.invoke()方法,通过反射调用目标类方法。最后就是生成代理类对象并初始化,调用方法查看结果,完成切面编程的过程。以junit进行单元测试,代码如下

 

        @Test
	public void taestProxy()
	{
		UserDao userDao = new UserDaoImpl();
		LogInterceptor li = new LogInterceptor();
		li.setTarget(userDao);
                //为编织了目标业务类逻辑和横切逻辑的LogInterceptor创建代理类
               UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), 
                                 userDao.getClass().getInterfaces(), li);
		proxy.save(new User());
		proxy.delete();
	}

 

上面的代码完成了业务类代码和横切代码编织和接口代理实例生成的工作,其中在li.setTarget(userDao)处,我们将LogInterceptor实例编织为一个包含业务逻辑和横切逻辑实例,然后在newProxyInstance处,通过Proxy的静态方法newProxyInstance()为融合了业务类逻辑和横切逻辑的LogInterceptor创建一个UserDao接口的代理实例,该方法的第一个入参为类加载器,第二个入参为创建的代理实例所要实现的一组接口,第三个参数是整合了业务逻辑和横切逻辑的编织器对象。简言之这三个参数分别是UserDaoImpl的类加载器、UserDao接口、实现了代理的类LogInterceptor对象,此时UserDaoImpl是被代理的对象


 

运行结果如下

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics