spring基于子类的动态代理方法
此处是基于接口的,可参照
基于接口的动态代理
本项目也是使用的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 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.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 模拟一个消费者
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();
final people smallming=new people();
/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码的基础上对方法增强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
* 基于子类的动态代理:
* 涉及的类:Enhancer
* 提供者:第三方cglib库
* 如何创建代理对象:
* 使用Enhancer类中的create方法
* 创建代理对象的要求:
* 被代理类不能是最终类
* create方法的参数:
* Class:字节码
* 它是用于指定被代理对象的字节码。
*
* Callback:用于提供增强的代码
* 它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
* 此接口的实现类都是谁用谁写。
* 我们一般写的都是该接口的子接口实现类:MethodInterceptor
*/
people cglibpeople = (people) Enhancer.create(smallming.getClass(), new MethodInterceptor() {
/**
* 执行北地阿里对象的任何方法都会经过该方法
* @param proxy
* @param method
* @param args
* 以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
* @param methodProxy :当前执行方法的代理对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//提供增强的代码
Object returnValue1=null;
Object returnValue2=null;
System.out.println("methodProxy"+methodProxy.toString());
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;
}
}
});
cglibpeople.myage(6);
cglibpeople.myname("改名");
}
}
结果展示
特意输出了methodProxy参数,可见每次代理不同的方法,methodProxy对象是不同的,但是同一个方法是一致的