动态代理功能就是实现业务代码与非业务代码实现解耦合的。
cglib动态代理具体代码演示如下:
第一步:创建业务目标类
package com.bjpowernode.service;
//目标类
public class SomeServiceImpl {
public String doSome(){
System.out.println("执行了业务方法doSome");
return "abcd";
}
}
第二步:创建方法拦截器类:实现功能增强
package com.bjpowernode.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//方法拦截器类, 实现功能的增强
public class MyInterceptor implements MethodInterceptor {
private Object target;
public MyInterceptor(Object target) {
super();
this.target = target;
}
public MyInterceptor() {
super();
// TODO Auto-generated constructor stub
}
/**
* intercept()等同于jdk中invoke()
* 作用:拦截用户的请求, 调用业务方法的时候,首先执行intercept
*
* 参数:
* Object obj:系统生成的代理对象
* Method method:正在执行的业务方法(目标方法)
* Object[] args:目标方法的参数列表
* MethodProxy proxy:目标方法的代理对象
*
* 返回
* Object:目标方法的执行结果(可以是修改后的结果)
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("==========intercept==========");
Object result = null;
//调用目标方法
result = method.invoke(target, args); //doSome()
//修改result的结果
if( result != null){
//实现小写转大写
String str = (String)result;
result = str.toUpperCase();
}
//返回目标方法的执行结果
return result;
}
}
第三步:创建代理对象
package com.bjpowernode.proxy;
import com.bjpowernode.service.SomeServiceImpl;
import net.sf.cglib.proxy.Enhancer;
public class ProxyFactory {
//定义工具方法,创建代理对象
public Object createProxy(Object target){
//1.创建cglib中的Enhancer对象
Enhancer en = new Enhancer();
//2.指定目标类对象
en.setSuperclass(SomeServiceImpl.class);
//3.指定方法拦截器对象
en.setCallback(new MyInterceptor(target));
//4.创建代理对象
return en.create();
}
}
第四步:编写测试方法,测试
package com.bjpowernode.test;
import com.bjpowernode.proxy.ProxyFactory;
import com.bjpowernode.service.SomeServiceImpl;
public class MyTest {
public static void main(String[] args) {
//创建目标对象
SomeServiceImpl target = new SomeServiceImpl();
//创建工具类对象
ProxyFactory factory = new ProxyFactory();
//调用工具方法
SomeServiceImpl proxy = (SomeServiceImpl) factory.createProxy(target);
System.out.println("proxy:"+proxy.getClass().getName());
//通过代理对象执行业务方法
String str = proxy.doSome();
System.out.println("通过代理对象执行业务方法的结果:"+str);
}
}
jdk动态代理具体代码演示:
第一步:定义业务接口与实现类以及非业务工具类
package com.bjpowernode.service;
public interface SomeService {
void doSome();
void doOther();
}
package com.bjpowernode.service;
import com.bjpowernode.utils.ServiceTools;
public class SomeServiceImpl implements SomeService {
//业务功能和非业务功能的耦合
@Override
public void doSome() {
//ServiceTools.doLog();
System.out.println("执行了业务方法doSome");
//ServiceTools.doTrans();
}
@Override
public void doOther() {
//ServiceTools.doLog();
System.out.println("执行了业务方法doOther");
//ServiceTools.doTrans();
}
//public void com.bjpowernode.service.SomeServiceImpl.doSome() throws Exception
//execution(* com.xyz.service..*.*(..))
//com.xyz.service.impl.OtherService
//com.xyz.service.SomeService
//execution(* *..service.*.*(..))
// com.service.OtherService
// cn.service.SomeService
// org.cn.service.FirstService
}
package com.bjpowernode.utils;
public class ServiceTools {
public static void doLog(){
System.out.println("非业务功能,打印日志");
}
public static void doTrans(){
System.out.println("非业务功能,事务处理");
}
}
第二步:创建处理器类,实现InvocationHandler接口
package com.bjpowernode.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import com.bjpowernode.utils.ServiceTools;
//使用jdk动态代理 处理器对象
public class MyInvocationHanlder implements InvocationHandler {
private Object target;
public MyInvocationHanlder(Object target) {
super();
this.target = target;
}
public MyInvocationHanlder() {
super();
// TODO Auto-generated constructor stub
}
/**
* invoke:能截取对目标方法的访问,调用
* 参数:
* Object proxy:系统生成的代理对象
* Method method:目标方法,业务方法
* Object[] args:目标方法的参数列表
* 返回
* Object:目标方法的执行结果(可以是修改后的结果)
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
String methodName = method.getName();
System.out.println("methodName:"+methodName);
if("doSome".equals(methodName)){
//在目标方法执行开始,加入日志
ServiceTools.doLog();
//目标方法的调用
result = method.invoke(target, args); //doSome
//在目标方法执行之后,提交事务
ServiceTools.doTrans();
} else {
// doOther()
//目标方法的调用
result = method.invoke(target, args); //doOther
}
//返回目标方法的执行结果
return result;
}
}
第三步:编写测试类,测试效果
package com.bjpowernode.test;
import java.lang.reflect.Proxy;
import com.bjpowernode.proxy.MyInvocationHanlder;
import com.bjpowernode.service.SomeService;
import com.bjpowernode.service.SomeServiceImpl;
public class MyTest {
public static void main(String[] args) {
//创建目标对象
SomeService target = new SomeServiceImpl();
//创建调用处理器对象
MyInvocationHanlder handler = new MyInvocationHanlder(target);
//创建代理对象
SomeService proxy = (SomeService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
//通过代理对象,执行业务方法,实现日志,事务的增强
System.out.println("proxy:"+proxy.getClass().getName());
proxy.doSome();
System.out.println("==================");
proxy.doOther();
}
}