代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
UML
静态代理
接口
public interface Movable {
void move();
}
需要增强的类
public class Person implements Movable{
@Override
public void move() {
System.out.println("Person is moving");
}
}
两个代理类
public class RunProxy implements Movable{
Movable m;
public RunProxy(Movable m) {
this.m = m;
}
@Override
public void move() {
m.move();
System.out.println("person is moving in running");
}
}
public class SingProxy implements Movable{
Movable m;
public SingProxy(Movable m) {
this.m = m;
}
@Override
public void move() {
m.move();
System.out.println("Person is moving with song");
}
}
调用
public class Main {
public static void main(String[] args) {
Movable m = new SingProxy(new RunProxy(new Person()));
m.move();
}
}
JDK中的动态代理
接口
public interface Movable {
void move();
}
代理实现
public class Person implements Movable{
@Override
public void move() {
System.out.println("person is moving");
}
public static void main(String[] args) {
Person person = new Person();
//System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFile","true");
Movable m = (Movable)Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Movable.class},new RunProxy(person));
/*new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method " + method.getName() + " start");
Object o = method.invoke(person, args);
System.out.println("method " + method.getName() + " end!");
return o;
}
});*/
m.move();
}
}
class RunProxy implements InvocationHandler{
Person person;
public RunProxy(Person person) {
this.person = person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("person is moving in running");
Object o = method.invoke(person, args);
return o;
}
}
cglib实现动态代理
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
class Tank {
public void move(){
System.out.println("Tank is moving");
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Tank.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
Object result = null;
result = methodProxy.invokeSuper(o, objects);
System.out.println("end");
return result;
}
});
Tank tank = (Tank) enhancer.create();
tank.move();
}
}
Spring AOP
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
public class Tank {
public void move(){
System.out.println("tank is moving");
}
}
@Aspect
public class RunProxy {
@Before("execution (void com.designpattern.test.springaop.s1.Tank.move())")
public void before(){
System.out.println("before");
}
@After("execution (void com.designpattern.test.springaop.s1.Tank.move())")
public void after(){
System.out.println("after");
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("app_auto.xml");
Tank t = (Tank)context.getBean("tank");
t.move();
}
}