Jdk动态代理和springAOP

               终于到了总结spring的入门了,ssh这三个框架中,spring是理解的最浅的,也是最需要话功夫研究了,今天只搞了一点点,不过也要记录下来。

先看看用jdk,怎样实现动态代理,首先我们需要使用Proxy,Proxy是专门用来完成代理操作的类,可以通过此类为一个或者多个接口动态的生成实现类,具体调用的方法为:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws illegalArgumentException

通过newProxyInstance()方法可以动态的生成实现类,该方法有三个参数:

1,ClassLoader loader :类加载器

2,Class<?>[] interfaces: 得到被代理类的全部接口

3,InvocationHandler h:   得到InvocationHandler 接口的子类实现类(通常我们需要加入的逻辑,就是在InvocationHandler的子类中来实现)

显然要使用动态代理就必须实现InvocationHandler的接口,InvocationHandler的定义中有一个invoke的抽象方法:

pubic Object invoke(Object Proxy,Method method,Object[] args该方法也有三个参数,分别如下:

1, Object proxy 表示被代理的对象

2, Method method 表示被代理类需要执行的方法

3, Object[] args 表示执行方法所需要的参数

为了演示动态代理的过程首先需要设计一个接口:userDaoinf 里面有两个方法,一个添加用户,一个删除用户

package edu.hue.jk.aop;

public interface userDaoInf {
	public void addUser();    // 添加用户
	
	public void deleteUser();// 删除用户
}

然后给出它的实现类,UserDao:
package edu.hue.jk.aop;

public class UserDao implements userDaoInf {

	public void addUser() {
		System.out.println("add user successful");
	}

	public void deleteUser() {
		System.out.println("delete user successful");
	}
	
}
实现InvocationHandler接口,MyInvocationHandler:在实现该接口的时候,根据不同的调用方法可以选择执行不同的逻辑:

package edu.hue.jk.aop;

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

public class MyInvocationHandler implements InvocationHandler {
	private Object object; // 被代理的类
	
	public Object getObject() {
		return object;
	}
	public void setObject(Object object) {
		this.object = object;
	}
	public void beforeMethod(){
		
		System.out.println("您拥有权限");
	}
	public Object invoke(Object proxy, Method method, Object[] args)  //使用invoke方法来动态的调用被代理类的方法
			throws Throwable {
		if(method.getName().equals("deleteUser")) // 根据不同的方法执行不同的逻辑,如果是deleteUser方法,则先执行beforeMethod()
		{
			beforeMethod();
			//System.out.println("methodName:"+method.getName());
			Object tem=method.invoke(this.object, args);
			return tem;
		}
		else {
			
			Object tem=method.invoke(this.object, args);
			return tem;
		}
		
	}

}
结果测试:<pre name="code" class="java">package edu.hue.jk.aop;

import java.lang.reflect.Proxy;

public class AopTest {
	
	
	public static void main(String[] args) {
		userDaoInf userDao=new UserDao();  // 生成代理类的目标对象
		MyInvocationHandler handler=new MyInvocationHandler();  // 需要织入的代码
		handler.setObject(userDao);  // 动态的调用userDao的方法
//		Class<?>[] inters= userDao.getClass().getInterfaces();
//		for(Class<?> o:inters)  // 打印所有的接口
//			System.out.println("interfaces :"+o.getName());
		//为userDao生成代理对象
		userDaoInf uproxy=(userDaoInf)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), handler);
		// 使用代理对象来完成操作
		uproxy.addUser();
		
		uproxy.deleteUser();
		System.out.println(uproxy.getClass().getName());  // 打印生成的代理类的名字
	}

}

 运行程序:  最后只在deleteUser()时候加入了  我们自己的逻辑 

add user successful
您拥有权限
delete user successful
$Proxy0
上面的程序实现了动态的代理的原理,那么spring的封装给我们带来了方便没有呢,同样的逻辑,我用spring实现如下:

定义一个UserService 的接口:

package edu.hue.jk.aop;

public interface UserService {
	public void addUser(); 
	public void deleteUser();
}
实现接口:

package edu.hue.jk.aop;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl implements UserService {

	public void addUser() {
		System.out.println("add User successful");
	}

	public void deleteUser() {
		System.out.println("delete user successful");
	}
	
}
配置切面aspect :
package edu.hue.jk.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component("loginter")
public class Loginter {
	@Before("execution(* edu.hue.jk.aop.UserServiceImpl.*())")  //在执行UserServiceImpl的所有方法之前先调用beforeMethod()的逻辑
	public void beforeMethod(){
		System.out.println("您拥有权限:");
	}
}
程序的测试代码:

package edu.hue.jk.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopTestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService service=(UserService)context.getBean("userService",UserService.class);
		service.addUser();
		
		service.deleteUser();
	}

}
最后结果:
您拥有权限:
add User successful
您拥有权限:

delete user successful

可见在执行两个方法都加入了自己添加的逻辑,也可以根据配置@before annotation 来修改。可见使用spring 配置切面来实现动态代理相比之下要简单的多,不用自己去实现InvocationHandler  接口。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值