[b]概述[/b]
代理模式主要有两种:静态代理和动态代理
[img]http://dl.iteye.com/upload/attachment/339719/4eae8cd2-b9a1-3837-880b-c8ff6688545f.jpg[/img]
静态代理类图之间的关系
[img]http://dl.iteye.com/upload/attachment/339723/e5f2aa70-75be-368f-9a8e-c64614ac3246.jpg[/img]
静态代理:比如要在输出“HelloWorld”前打印一个字符串“Welcome”
A:先定义一个接口类
B:再定义一个实现类
C:定义一个静态代理类
D:测试类
E:总结:
可以看出静态代理类有一个很不爽的缺点:如果接口加一个方法,所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。
动态代理
动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
动态代理类图之间的关系
[img]http://dl.iteye.com/upload/attachment/339721/7466d0b8-9e8e-3577-a234-225c18005ea5.jpg[/img]
JDK提供的代理只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类。
如果想对类进行代理,可以使用Spring中的CGLib,代理类都需要实现MethodInterceptor接口。
测试类
代理模式主要有两种:静态代理和动态代理
[img]http://dl.iteye.com/upload/attachment/339719/4eae8cd2-b9a1-3837-880b-c8ff6688545f.jpg[/img]
静态代理类图之间的关系
[img]http://dl.iteye.com/upload/attachment/339723/e5f2aa70-75be-368f-9a8e-c64614ac3246.jpg[/img]
静态代理:比如要在输出“HelloWorld”前打印一个字符串“Welcome”
A:先定义一个接口类
package com.mypack.proxy;
public interface HelloWorld {
public void sayHelloWorld();
}
B:再定义一个实现类
package com.mypack.proxy;
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println("Hello World....");
}
}
C:定义一个静态代理类
package com.mypack.proxy;
public class StaticProxyFactory implements HelloWorld {
private HelloWorld helloWorld;
public StaticProxyFactory(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
@Override
public void sayHelloWorld() {
System.out.print("Welcome:");
helloWorld.sayHelloWorld();
}
}
D:测试类
package com.mypack.proxy;
import org.junit.Test;
public class Demo {
@Test
public void testHelloWorld() {
HelloWorld helloWorld = new HelloWorldImpl();
StaticProxyFactory staticProxyFactory = new StaticProxyFactory(helloWorld);
staticProxyFactory.sayHelloWorld();
}
}
E:总结:
可以看出静态代理类有一个很不爽的缺点:如果接口加一个方法,所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。
动态代理
动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
动态代理类图之间的关系
[img]http://dl.iteye.com/upload/attachment/339721/7466d0b8-9e8e-3577-a234-225c18005ea5.jpg[/img]
JDK提供的代理只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类。
package com.mypack.service;
public interface PersonService {
public void save();
}
package com.mypack.service.impl;
import com.mypack.service.PersonService;
public class PersonServiceBean implements PersonService {
private String user;
public PersonServiceBean() {
}
public PersonServiceBean(String user) {
this.user = user;
}
public void save() {
System.out.println("我是save()方法..........");
}
public String getUser() {
return user;
}
}
package com.mypack.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mypack.service.impl.PersonServiceBean;
public class JDKProxyFactory implements InvocationHandler {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
//Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时执行InvocationHandler的invoke方法
return Proxy.newProxyInstance(this.targetObject.getClass()
.getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceBean personServiceBean = (PersonServiceBean) this.targetObject;
Object result = null;
if (personServiceBean.getUser() != null) {
result = method.invoke(this.targetObject, args);
}
return result;
}
}
如果想对类进行代理,可以使用Spring中的CGLib,代理类都需要实现MethodInterceptor接口。
package com.mypack.aop;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import com.mypack.service.impl.PersonServiceBean;
public class CGLIBProxyFactory implements MethodInterceptor {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
// 新建Enhancer对象
Enhancer enhancer = new Enhancer();
// 设置代理目标类
enhancer.setSuperclass(this.targetObject.getClass());
// 方法被拦截时,执行intercept方法。
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object proxyObject, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
PersonServiceBean personServiceBean = (PersonServiceBean) this.targetObject;
Object result = null;
if (personServiceBean.getUser() != null) {
result = method.invoke(this.targetObject, args);
}
return result;
}
}
测试类
package com.mypack.test;
import org.junit.BeforeClass;
import org.junit.Test;
import com.mypack.aop.CGLIBProxyFactory;
import com.mypack.aop.JDKProxyFactory;
import com.mypack.service.PersonService;
import com.mypack.service.impl.PersonServiceBean;
public class Demo {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void testJDKProxySave() {
JDKProxyFactory factory = new JDKProxyFactory();
PersonService personService = (PersonService) factory
.createProxyInstance(new PersonServiceBean("liudong"));
personService.save();
}
@Test
public void testCGLIBProxySave() {
CGLIBProxyFactory factory = new CGLIBProxyFactory();
PersonService personService = (PersonService) factory
.createProxyInstance(new PersonServiceBean("liudong"));
personService.save();
}
}