1、代理模式
代理模式是23中设计模式中的一种,它是为了在目标对象的基础上增加额外的功能,也就是扩展对象的功能。
在编译期阶段否能决定最终的执行方法可以把代理模式分为动态代理和静态代理。
2、静态代理
我们目标是一个人在跑步,现在我们在不该原来的代码基础上,增加套马甲的功能。
定义一个接口:
public interface PersonDao {
void run();
}
实现一个基础类:
public class Person implements PersonDao{
@Override
public void run(){
System.out.println("我在跑步");
}
}
实现一个代理类:
public class PersonProxy implements PersonDao{
Person person;
public PersonProxy(Person person) {
this.person = person;
}
@Override
public void run() {
System.out.println("我先套个马甲");
person.run();
}
}
测试类:
@Test
void test4(){
Person p1 = new Person();
PersonProxy personProxy = new PersonProxy(p1);
personProxy.run();
}
3、动态代理
3.1 cglib动态代理
这个代理模式需要我们自己导包:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
实体类:
public class UserService {
public void run(){
System.out.println("我还是在跑步!!!");
}
}
接口实现:
public class AutoMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("先热个身");
Object object = methodProxy.invokeSuper(obj, args);
return object;
}
}
测试:
@Test
void test6(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new AutoMethodInterceptor());
UserService userService = (UserService)enhancer.create();
userService.run();
}
3.2 JDK动态代理
Java提供了 java.lang.reflect.Proxy
和 java.lang.reflect.InvocationHandler
两个类来实现JDK代理。
代理类:实现InvocationHandler
public class PersonHandler implements InvocationHandler {
private PersonDao personDao;
public PersonHandler(PersonDao personDao) {
this.personDao = personDao;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("先进行热身运动");
Object invoke = method.invoke(personDao, args);
System.out.println("结束进行放松运动");
return invoke;
}
}
测试:
@Test
void test5(){
Person person = new Person();
PersonHandler personHandler = new PersonHandler(person);
PersonDao personProxy= (PersonDao) Proxy.newProxyInstance(
person.getClass().getClassLoader(),
person.getClass().getInterfaces(),
personHandler
);
personProxy.run();
}