基于Aop思想,面向切面,这里使用了两种方法代理对象,实现对每一个对象的方法进行代理。
(1)第一种方法:采用JdkProxy创建代理对象,此方法必要条件必须实现接口。
(2)第二种方法:采用cglib-nodep jar包中Enhancer创建代理对象,该方法好处:被代理的对象不需要实现接口就可以创建代理对象
代码如下:
1.两种方法创建的代理对象工厂
package com.yang;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
/**
* 文件名称: 该类提供了两种方法创建代理对象</br>
* 初始作者: bk_yzw</br>
* 创建日期: 2017年11月23日</br>
* 功能说明: 这里用一句话描述这个类的作用--此句话需删除 <br/>
* =================================================<br/>
* 修改记录:<br/>
* 修改作者 日期 修改内容<br/>
* ================================================<br/>
* Copyright (c) 2010-2011 .All rights reserved.<br/>
*/
public class JDKProxyFactory {
private Object obj;
// (1)第一种方式通过JdkProxy创建代理对象,必要要求:被代理的类要实现接口
public Object createProxy(Object obj) {
this.obj = obj;
// 创建代理对象
// 该方法第三个参数需要实现InvocationHandler接口
return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(), this.obj.getClass().getInterfaces(),
(InvocationHandler) obj);
}
// (2)第二种方式通过cglib-nodep jar包中创建代理对象,该方法好处:被代理的对象不需要实现接口就可以创建代理对象
public Object createProxyIntance(Object obj) {
this.obj = obj;
Enhancer enhancer = new Enhancer();
// 将用户类设为 Enhancer对象的superclass属性,,即设为 Enhancer对象的父类
enhancer.setSuperclass(this.obj.getClass());
// 设 Enhancer对象的Callbacks属性,要求必须是Callback接口类型
// 设置回调
//该参数对象必须实现MethodInterceptor接口
enhancer.setCallback((Callback) this.obj);
return enhancer.create();// 创建代理对象
}
}
2.接口
public interface PersonService {
String getUserName();
boolean save(String userName);
boolean update(String userName);
}
3.具体代理的类,实现代理操作,注:两种方法合并来写,采取一种即可
package com.yang;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 文件名称: com.yang.PersonServiceImpl.java</br>
* 初始作者: bk_yzw</br>
* 创建日期: 2017年11月23日</br>
* 功能说明: 这里用一句话描述这个类的作用--此句话需删除 <br/>
* =================================================<br/>
* 修改记录:<br/>
* 修改作者 日期 修改内容<br/>
* ================================================<br/>
* Copyright (c) 2010-2011 .All rights reserved.<br/>
*/
public class PersonServiceImpl implements PersonService, InvocationHandler, MethodInterceptor {
private String userName = null;
public PersonServiceImpl() {
super();
}
public PersonServiceImpl(String userName) {
super();
this.userName = userName;
}
@Override
public String getUserName() {
return userName;
}
@Override
public boolean save(String userName) {
System.out.println("这是一个保存方法" + userName);
return true;
}
@Override
public boolean update(String userName) {
System.out.println("这是一个修改方法" + userName);
return true;
}
/**
* 方法描述: [采用第实现接口方式代理,当执行被代理类的方法时时执行该方法.]</br>
* 初始作者: bk_yzw<br/>
* 创建日期: 2017年11月24日-上午9:56:58<br/>
* 开始版本: 2.0.0<br/>
* =================================================<br/>
* 修改记录:<br/>
* 修改作者 日期 修改内容<br/>
* ================================================<br/>
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if (userName != null) {
result=method.invoke(this, args);
System.out.println("invoke+true");
}
return result;
}
/**
* 方法描述: [采用cglib-nodep jar方式代理,当执行被代理类的方法时时执行该方法.]</br>
* 初始作者: bk_yzw<br/>
* 创建日期: 2017年11月24日-上午10:15:33<br/>
* 开始版本: 2.0.0<br/>
* =================================================<br/>
* 修改记录:<br/>
* 修改作者 日期 修改内容<br/>
* ================================================<br/>
*/
@Override
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
Object result = null;
if (userName != null) {
try{
//前置通知
result = proxy.invoke(this, arg);
//后置通知
System.out.println("invoke+true2");
}catch(Exception e){
//异常通知
}finally{
//最终通知
}
}
return result;
}
}
4.测试:
package com.yang;
import org.junit.Test;
public class TestProxy {
@Test
public void myTest() {
JDKProxyFactory fact = new JDKProxyFactory();
PersonServiceImpl per = new PersonServiceImpl("xx");
//第一种方式
PersonService rest = (PersonService) fact.createProxy(per);
System.out.println(rest.save("xxx1"));
}
@Test
public void myIntanceTest() {
JDKProxyFactory fact = new JDKProxyFactory();
PersonServiceImpl per = new PersonServiceImpl("xx");
//第二种方式
PersonService rest = (PersonService) fact.createProxyIntance(per);
System.out.println(rest.save("xxx1"));
}
}
学习心得
通过对这两种代理方法的理解,明白了前置通知,后置通知,异常通知,最终通知都作用再什么地方,
横切性关注点:如被代理对象
切面(Aspect):横切性关注点关注点的抽象,即实现代理对象的这些代码