目录
写在前面,后文所写到的所有代码,前提是要在pom.xml文件里添加以下代码:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
代理模式分为静态代理和动态代理。核心功能是方法增强。
一、静态代理
比如,一个歌手要开演唱会,歌手只负责唱歌,其他事宜则有经纪人去办,经纪人就相当于一个代理工厂,替歌手搞定其他事。
第一种,实现相同的接口
(一)、新建歌手接口
public interface Singer {
/**
* 唱歌
*/
void sing();
}
(二)、新建男歌手类
public class MaleSinger implements Singer {
@Override
public void sing() {
System.out.println("周杰伦要去唱歌了");
}
}
(三)、新建代理人
public class Agent implements Singer{
private Singer singer;
public Agent(Singer singer) {
this.singer = singer;
}
@Override
public void sing() {
System.out.println("协商价钱,会场等工作");
// 一定是歌手去唱歌
singer.sing();
System.out.println("费用结算");
}
}
(四)、测试类
public class Client {
public static void main(String[] args) {
Singer singer = new MaleSinger();
Agent agent = new Agent(singer);
agent.sing();
}
}
(五)、运行结果
第二种,代理者继承被代理者
(一)、新建男歌手类
public class MaleSinger{
public void sing() {
System.out.println("周杰伦要去唱歌了");
}
}
(二)、新建代理人类,继承男歌手
public class Agent extends MaleSinger{
private MaleSinger singer;
public Agent(MaleSinger singer) {
this.singer = singer;
}
@Override
public void sing() {
System.out.println("协商价钱,会场等工作");
// 一定是歌手去唱歌
singer.sing();
System.out.println("费用结算");
}
}
(三)、测试类
public class Client {
public static void main(String[] args) {
MaleSinger singer = new MaleSinger();
Agent agent = new Agent(singer);
agent.sing();
}
}
( 四)、运行结果
二、动态代理
静态代理的代理类是我们写的,动态代理的代理类是动态生成的。
动态代理分为基于接口的动态代理和基于类的动态代理。
第一种,基于接口的动态代理——JDK动态代理
(一)、新建歌手接口
public interface Singer {
/**
* 唱歌
*/
void sing();
void say();
}
(二)、新建男歌手类继承歌手
public class MaleSinger implements Singer {
@Override
public void sing() {
System.out.println("周杰伦要去唱歌了");
}
@Override
public void say() {
System.out.println("周杰伦开始说唱了");
}
}
(三)、新建代理类,编写动态代理代码。
public class Agent implements InvocationHandler {
private Object object;
public Agent(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
Object invoke = method.invoke(object, args);
System.out.println("提交");
return invoke;
}
}
(四)、新建测试类
public class Client {
public static void main(String[] args) {
//该设置用于输出jdk动态代理产生的类
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Singer maleSinger = new MaleSinger();
Singer singer = (Singer) Proxy.newProxyInstance(Client.class.getClassLoader(),
new Class[]{Singer.class},
new Agent(maleSinger));
// 此处的say()可替换成maleSinger里的任意方法
singer.say();
}
}
(五)、运行结果
第二种,基于类的动态代理——cglib
pom.xml中添加依赖
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
(一)、新建歌手接口
public interface Singer {
/**
* 唱歌
*/
void sing();
void say();
}
(二)、新建男歌手类继承歌手
public class MaleSinger2{
public void sing() {
System.out.println("周杰伦要去唱歌了");
}
public void say() {
System.out.println("周杰伦开始说唱了");
}
}
(三)新建测试类
public class Client2 {
public static void main(String[] args) {
//该设置用于输出cglib动态代理产生的类
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");
// 1、定义增强器Enhancer
Enhancer enhancer = new Enhancer();
// 2、设置一个超类
enhancer.setSuperclass(MaleSinger2.class);
// 3、设置方法拦截器,拦截老的方法,把它增强了变成新的方法
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("begin");
Object invoke = methodProxy.invokeSuper(o,objects);
System.out.println("end");
return invoke;
}
});
MaleSinger2 maleSinger2 = (MaleSinger2)enhancer.create();
maleSinger2.say();
}
}
(四)、运行结果