总结:一、四种invoke方法的不同实现手段(四种生成代理类的方法),第一种是通过重写InvocationHandler中的invoke
第二种和第三种是通过InvocationHandler的匿名内部类实现(其中第三种用final修饰目标对象,不用在内部创建,也不用通过实现类UserHandler.this.targetObject的这种方式调用,而是在invoke方法中直接调用)
第四种是创建一个继承了InvocationHandler接口的中间类,并在该类中实现invoke方法,
二、
Jdk动态代理只针对接口的实现类
三、CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。
同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。
CGLib是第三方,不是jdk带的。用它就要导入CGLib的jar包。
(一) 继承InvocationHandler接口,实现其方法(拦截并增强),返回代理对象
package com.soft.service4;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.jsp.tagext.TryCatchFinally;
//JDK动态代理 四种方法生成代理(一)、继承InvocationHandler接口,实现其方法(拦截并增强),返回代理对象
public class UserHandler implements InvocationHandler{
private Object targetObject;//私有的目标对象
//返回一个代理对象
public Object newProxy(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
this);//继承并实现了InvocationHandler的当前类(即UserHandler)
}
//当目标对象中的方法被调用时就会执行invoke方法,所以在此方法中实现方法的增强
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
checkBefore();
Object ret = null;//声明返回值
try{
ret = method.invoke(targetObject, args) ;//捕获每一个方法并调用
}catch (Exception e) {
e.printStackTrace();
}
checkAfter();
return ret;
}
public void checkBefore(){
System.out.println("---Before----");
}
public void checkAfter(){
System.out.println("---After----");
}
}
(二)用InvocationHandler的匿名内部类,不用继承InvocationHandler,内部实现invoke方法
package com.soft.service4;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.jsp.tagext.TryCatchFinally;
//JDK动态代理 四种方法生成代理(二)、使用InvocationHandler的匿名内部类,不用继承InvocationHandler,内部实现invoke方法
public class UserHandler1 {
private Object targetObject;//私有的目标对象
//返回一个代理对象
public Object newProxy( Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
new InvocationHandler() {
//当目标对象中的方法被调用时就会执行invoke方法,所以在此方法中实现方法的增强
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
checkBefore();
Object ret = null;//声明返回值
try{
ret = method.invoke(UserHandler1.this.targetObject, args) ;//捕获每一个方法并调用
}catch (Exception e) {
e.printStackTrace();
}
checkAfter();
System.out.println("--匿名内部类实现----");
System.out.println(ret);
System.out.println(method.getName());
for(Object x :args){
System.out.println(x.toString());
}
return ret;
}
});//继承并实现了InvocationHandler的当前类(即UserHandler)
}
public void checkBefore(){
System.out.println("---Before----");
}
public void checkAfter(){
System.out.println("---After----");
}
}
(三)InvocationHandler的匿名内部类,使用final的targetObject,
不用再创建目标对象,内部类中直接调用(而不是UserHandler2.this.targetObject)
package com.soft.service4;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.jsp.tagext.TryCatchFinally;
//JDK动态代理 四种方法生成代理(二)、InvocationHandler的匿名内部类,使用final的targetObject,
//不用再创建目标对象,内部类中直接调用(而不是UserHandler2.this.targetObject)
//只要实现了InvocationHandler接口,可以代理所有接口
public class UserHandler2 {
//返回一个代理对象
public Object newProxy( final Object targetObject){
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
new InvocationHandler() {
//当目标对象中的方法被调用时就会执行invoke方法,所以在此方法中实现方法的增强
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
checkBefore();
Object ret = null;//声明返回值
try{
ret = method.invoke(targetObject, args) ;//终态的targetObject直接调用
}catch (Exception e) {
e.printStackTrace();
}
checkAfter();
System.out.println("--匿名内部类实现----");
System.out.println(ret);
System.out.println(method.getName());
for(Object x :args){
System.out.println(x.toString());
}
return ret;
}
});//继承并实现了InvocationHandler的当前类(即UserHandler)
}
public void checkBefore(){
System.out.println("---Before----");
}
public void checkAfter(){
System.out.println("---After----");
}
}
(四)创建一个受保护的类继承InvocationHandler接口,并实现invoke方法,调用时传入目标对象创建代理对象
package com.soft.service4;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.jsp.tagext.TryCatchFinally;
//JDK动态代理 四种方法生成代理(二)、创建一个受保护的类继承InvocationHandler接口,并实现invoke方法,调用时传入目标对象创建代理对象
//只要实现了InvocationHandler接口,可以代理所有接口
public class UserHandler3 {
//返回一个代理对象
public Object newProxy( final Object targetObject){
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
new custInvocationHandler(targetObject));
}
class custInvocationHandler implements InvocationHandler{
private Object targetObject;
public custInvocationHandler(Object targetObject){
this.targetObject = targetObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
checkBefore();
Object ret = null;//声明返回值
try{
ret = method.invoke(targetObject, args) ;//终态的targetObject直接调用
}catch (Exception e) {
e.printStackTrace();
}
checkAfter();
System.out.println("--匿名内部类实现333----");
System.out.println(ret);
System.out.println(method.getName());
for(Object x :args){
System.out.println(x.toString());
}
return ret;
}
}
public void checkBefore(){
System.out.println("---Before----");
}
public void checkAfter(){
System.out.println("---After----");
}
}
Cglib代理没有实现接口的类,也可以实现有接口的代理类
package com.soft.service6;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLibProxy implements MethodInterceptor {
private Enhancer enhancer =new Enhancer();
public Object getProxy(Class clazz){
//设置需要创建子类的类
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);//设置回调函数
//通过字节码技术动态创建子类实例
return enhancer.create();
}
@Override
public Object intercept(Object object, Method method, Object[] arg2,
MethodProxy proxy) throws Throwable {
System.out.println("--前置代理");
Object result = proxy.invokeSuper(object, arg2);
System.out.println("---后置代理");
return result;
}
}
test
public static void main(String[] args) {
CGLibProxy cglibProxy = new CGLibProxy();
//没有继承接口的类,通过CGlib给该类生成子类代理
/*SayHello sayHello = (SayHello) cglibProxy.getProxy(SayHello.class);
sayHello.say();*/
UserManager userManager = (UserManager) cglibProxy.getProxy(UserManagerImpl.class);
userManager.addUser("ada", "124");
}
没有实现接口的类生成代理类只需传入该类类型,实现了接口的传入实现类的类型(都是创建子类代理)