基本环境的配置
本项目也是使用的maven管理工具,动态代理时基于JVM实现的,主要包含接口和子类实现的代理,本案例时基于接口实现代理。
注:代理的类必须使用接口
主要包括如下包。asm和cglib是子类代理所需要的。
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>com.itheima</groupId>
<artifactId>day03_eesy_02proxy</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_3</version>
</dependency>
</dependencies>
</project>
创建需要代理类和接口
本案例展示多函数代理实现,因此里面类中设置了两个函数。
接口:
package com.itheima.proxy;
public interface IPpeople {
public void myage(int age);
public void myname(String name);
}
实现类
package com.itheima.proxy;
public class people implements IPpeople {
@Override
public void myage(int age) {
System.out.println(age);
}
@Override
public void myname(String name) {
System.out.println("my name is "+name);
}
}
代理类的实现
package com.itheima.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 模拟一个消费者
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();
final people smallming= new people();
/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码的基础上对方法增强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
* 基于接口的动态代理:
* 涉及的类:Proxy
* 提供者:JDK官方
* 如何创建代理对象:
* 使用Proxy类中的newProxyInstance方法
* 创建代理对象的要求:
* 被代理类最少实现一个接口,如果没有则不能使用
* newProxyInstance方法的参数:
* ClassLoader:类加载器
* 它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法。
* Class[]:字节码数组
* 它是用于让代理对象和被代理对象有相同方法。固定写法。
* InvocationHandler:用于提供增强的代码
* 它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
* 此接口的实现类都是谁用谁写。
*/
final IPpeople proxypeople=(IPpeople)Proxy.newProxyInstance(smallming.getClass().getClassLoader(), smallming.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object returnValue1=null;
Object returnValue2=null;
if ("myname".equals(method.getName()))
{ String name=(String) args[0];
System.out.println(name);
returnValue1=method.invoke(smallming,"xiaoming1");
return returnValue1;
}
else
{
System.out.println(method.getName());
returnValue2=method.invoke(smallming,6);
return returnValue2;
}
}
});
proxypeople.myname("xiaoming2");
proxypeople.myage(5);
}
}
结果展示
结果分析
通过结果我们可以发现,
1.我们在想利用多个函数在一个代理类中时,需要我们自己加if语句进行判断,代理类不知道你调用什么函数,多函数下应该自己加条件。
2.动态代理中可以进行函数增强,并且以代理类中的操作为首要执行。