前置知识之代理模式
代理模式就是为其他对象提供一个代理对象,以控制或者增强目标对象
准备
创建 maven 工程,pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.spring.ss</groupId>
<artifactId>spring03-proxy</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<spring.verson>5.3.9</spring.verson>
<junit.version>5.7.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建接口
package org.spring.ss.service;
public interface ISomeService {
public String doSome(String msg);
public String doSome2(String name, String msg);
}
创建实现类
package org.spring.ss.service.impl;
import org.spring.ss.service.ISomeService;
public class SomeService implements ISomeService {
@Override
public String doSome(String msg) {
System.out.println("目标对象执行了。。。");
return msg;
}
@Override
public String doSome2(String name, String msg) {
System.out.println("不代理");
return msg;
}
}
静态代理
直接将代理对象声明出来,容易理解,但是不够灵活。
package org.spring.ss;
import org.spring.ss.service.ISomeService;
public class StaticSomeProxy implements ISomeService {
// 需要增强的目标对象
private ISomeService someService;
public StaticSomeProxy(ISomeService target) {
this.someService = target;
}
@Override
public String doSome(String msg) {
System.out.println("目标对象执行之前的操作");
String s = this.someService.doSome(msg);
System.out.println("目标对象执行之后的操作");
return s.toUpperCase();
}
@Override
public String doSome2(String name, String msg) {
return null;
}
}
添加测试方法
package org.spring.ss;
import org.junit.jupiter.api.Test;
import org.spring.ss.service.ISomeService;
import org.spring.ss.service.impl.SomeService;
public class ProxyTest {
@Test
public void doSomeTest1() {
ISomeService target = new SomeService();
ISomeService proxy = new org.spring.ss.StaticSomeProxy(target);
String nihao = proxy.doSome("nihao");
System.out.println(nihao);
}
}
执行结果:
动态代理之JDK的实现
如果目标实现的有接口,那么我们就可以使用JDK代理模式。
直接在测试方法中使用。
package org.spring.ss;
import org.junit.jupiter.api.Test;
import org.spring.ss.service.ISomeService;
import org.spring.ss.service.impl.SomeService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
@Test
public void doSomeTest2() {
ISomeService target = new SomeService();
ISomeService proxy = (ISomeService) Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 类加载器
target.getClass().getInterfaces(), // 目标对象实现的接口数组
/*
* 当代理对象执行相关方法的时候,会执行的逻辑
* */
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 调用目标对象的方法
System.out.println("目标对象执行之前的操作");
String msg = (String) method.invoke(target, args[0]);
System.out.println("目标对象执行之后的操作");
return msg.toUpperCase();
}
}
);
String nihao = proxy.doSome("nihao");
System.out.println(nihao);
}
}
执行结果:
动态代理之cglib
如果目标对象没有实现任何的接口那么我们是使用不了JDK
动态代理的,那么这个时候我们只能使用CGLIB
代理。CGLIB
的本质其实的代理类继承了目标对象,并重写相关方法。
引入CGLIB
的依赖
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
创建代理类
package org.spring.ss.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.spring.ss.service.impl.SomeService;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private SomeService target;
public CglibProxy(SomeService target) {
this.target = target;
}
// 创建代理对象
public SomeService createProxy() {
Enhancer enhancer = new Enhancer();
// 指定父类
enhancer.setSuperclass(SomeService.class);
// 指定回调方法
enhancer.setCallback(this);
// 创建代理对象
return (SomeService) enhancer.create();
}
// 需要执行具体的代理方法
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before...");
System.out.println(method.getName());
String msg = (String) method.invoke(target, objects[0]);
System.out.println("after...");
return msg.toUpperCase();
}
}
添加测试。
package org.spring.ss;
import org.junit.jupiter.api.Test;
import org.spring.ss.proxy.CglibProxy;
import org.spring.ss.service.ISomeService;
import org.spring.ss.service.impl.SomeService;
public class ProxyTest {
@Test
public void doSomeByCglibProxyTest() {
ISomeService target = new CglibProxy(new SomeService()).createProxy();
System.out.println(target.doSome("haha,hello , lilei"));
// System.out.println(target.doSome2("aa", "haha,hello , lilei222"));
}
}
执行结果