动态代理:
JVM可以在运行期间动态生成出类的字节码,这种动态生成的类被使用做代理类,即动态代理类
JVM生成的动态类只能作具有相同接口的目标类的代理(必须生成一个或多个接口)
如果想要作为代理类,这个类又没有实现一个或多个接口
static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException返回代理类的 java.lang.Class
对象,并向其提供类加载器和接口数组。该代理类将由指定的类加载器定义,并将实现提供的所有接口。如果类加载器已经定
义了具有相同排列接口的代理类,那么现有的代理类将被返回;否则,类加载器将动态生成并定义这些接口的代理类。
* Proxy.getProxyClass 获得动态产生的类
生成的动态类,只有一个构造方法,参数是Invocationhandler对象
每次使用代理调用方法的时候,都会调用InvocationHandler对象的invoke方法
package it.cast.day10;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyTest {
/**
* @param args
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws SecurityException
*/
public static void main(String[] args) throws IllegalArgumentException,
InstantiationException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException {
// TODO Auto-generated method stub
/**
* Proxy.getProxyClass 获得动态产生的类
*/
// JVM可以动态的生成类,这种动态生成的类被用作代理
Class<?> clazzProxy1 = Proxy.getProxyClass(
Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
System.out.println("---------begin constructors list---------");
// 测试动态生成的代理类的构造方法
Constructor[] constructors = clazzProxy1.getConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
// 获取参数的Class对象
Class[] clazzParams = constructor.getParameterTypes();
for (Class clazzParam : clazzParams) {
String name2 = clazzParam.getName();
String name3 = name2.substring(name2.lastIndexOf(".") + 1);
sBuilder.append(name3).append(",");
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder);
}
/**
* 反射出所有的字段
*/
System.out.println("-------------begin field list---------");
Field[] fields = clazzProxy1.getFields();
for (Field field : fields) {
if (field == null) {
System.out.println("Field is null");
break;
}
System.out.println(field.get(clazzProxy1));
}
/**
* 反射出所有的方法
*/
System.out.println("---------begin methods list---------");
// 测试动态代理类的所有方法
Method[] methods = clazzProxy1.getMethods();
for (Method method : methods) {
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for (Class clazzParam : clazzParams) {
/*
* String name2 = clazzParam.getName(); String name3
* =name2.substring(name2.lastIndexOf(".")+1);
*/
sBuilder.append(clazzParam.getName()).append(",");
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder);
}
System.out.println("---------begin create instance Object----");
// 创建动态代理的对象,使用字节码获取构造器
Constructor constructor = clazzProxy1
.getConstructor(InvocationHandler.class);
// 自定义了一个InvocationHandler的实现类
class myInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
System.out.println("——————————匿名内置类_______-");
Collection proxy1 = (Collection) constructor
.newInstance(new myInvocationHandler());
System.out.println(proxy1);
Collection proxy2 = (Collection) constructor
.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// TODO Auto-generated method stub
return null;
}
});
// 抽取方法
System.out.println("________Method Extract________");
final ArrayList target = new ArrayList();
Collection<String> proxy3 = (Collection<String>) getProxy(target,
new MyAdvice());
/**
* Client程序调用代理对象proxy3.add()设计三要素(代理对象,方法,参数)
*/
// 使用代理类调用目标的方法,会调用InvocationHandler对象的invoke方法
proxy3.add("wzm");
proxy3.add("zcz");
proxy3.add("zyz");
// proxy3.removeAll(proxy3);
System.out.println(proxy3.size());
}
private static Object getProxy(final Object target, final Advice advice) {
Object proxy3 = Proxy.newProxyInstance(target.getClass()
.getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
advice.beginMethod(method);
Object object = method.invoke(target, args);
if (args != null) {
for (Object arg : args) {
System.out.println("arg = " + arg);
}
}
advice.endMethod(method);
return object;
}
});
return proxy3;
}
}
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
package it.cast.day10.aopFramework;
import java.io.InputStream;
import java.util.Collection;
public class AopFrameworkTest {
/**
* @param args
*/
public static void main(String[] args) {
/**
* 直接用Class 加载资源
*/
//使用Class对象直接加载文件,返回值是流对象
InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
//AopFrameworkTest.class.getClassLoader().getResourceAsStream("config.properties");
Object bean = new BeanFactory(ips).getBean("xxx");
System.out.println(bean.getClass().getName());
((Collection)bean).clear();
}
}
BeanFactory————————————————————————————————————————————————————
package it.cast.day10.aopFramework;
import it.cast.day10.Advice;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
Properties pros = new Properties();
public BeanFactory(InputStream ips) {
try {
pros.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getBean(String name) {
//获取类名
String className = pros.getProperty(name);
Object bean = null;
try {
//获取类的Class对象
Class clazz = Class.forName(className);
//创建bean对象
bean = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
//判断,如果是代理,返回代理。不是代理就返回bean对象
if (bean instanceof ProxyFactoryBean) {
Object proxy = null;
try {
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean) bean;
Advice advice = (Advice) Class.forName(
pros.getProperty(name + ".advice")).newInstance();
// System.out.println(advice.getClass().getName());
//获取目标对象
Object target = Class.forName(
pros.getProperty(name + ".target")).newInstance();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
//获取代理对象
proxy = proxyFactoryBean.getProxy();
} catch (Exception e) {
e.printStackTrace();
}
//是代理对象就返回代理对象
return proxy;
}
return bean;
}
}
ProxyBeanFactory_______________________________________________________
package it.cast.day10.aopFramework;
import it.cast.day10.Advice;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactoryBean {
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Advice getAdvice() {
return advice;
}
public void setAdvice(Advice advice) {
this.advice = advice;
}
private Object target ;
private Advice advice;
//返回代理对象
public Object getProxy()
{
//动态代理
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().
getInterfaces(),
new InvocationHandler() {
//覆盖了InvocationHandler的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
advice.beginMethod(method);
//在这个方法中调用目标的方法
Object retVal = method.invoke(target, args);
advice.endMethod(method);
System.out.println(retVal);
return retVal;
}
}
);
return proxy;
}
}
配置文件
#xxx=java.util.ArrayList
xxx=it.cast.day10.aopFramework.ProxyFactoryBean
xxx.advice=it.cast.day10.MyAdvice
xxx.target=java.util.ArrayList
JVM可以在运行期间动态生成出类的字节码,这种动态生成的类被使用做代理类,即动态代理类
JVM生成的动态类只能作具有相同接口的目标类的代理(必须生成一个或多个接口)
如果想要作为代理类,这个类又没有实现一个或多个接口
static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException返回代理类的 java.lang.Class
对象,并向其提供类加载器和接口数组。该代理类将由指定的类加载器定义,并将实现提供的所有接口。如果类加载器已经定
义了具有相同排列接口的代理类,那么现有的代理类将被返回;否则,类加载器将动态生成并定义这些接口的代理类。
* Proxy.getProxyClass 获得动态产生的类
生成的动态类,只有一个构造方法,参数是Invocationhandler对象
每次使用代理调用方法的时候,都会调用InvocationHandler对象的invoke方法
package it.cast.day10;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyTest {
/**
* @param args
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws SecurityException
*/
public static void main(String[] args) throws IllegalArgumentException,
InstantiationException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException {
// TODO Auto-generated method stub
/**
* Proxy.getProxyClass 获得动态产生的类
*/
// JVM可以动态的生成类,这种动态生成的类被用作代理
Class<?> clazzProxy1 = Proxy.getProxyClass(
Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
System.out.println("---------begin constructors list---------");
// 测试动态生成的代理类的构造方法
Constructor[] constructors = clazzProxy1.getConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
// 获取参数的Class对象
Class[] clazzParams = constructor.getParameterTypes();
for (Class clazzParam : clazzParams) {
String name2 = clazzParam.getName();
String name3 = name2.substring(name2.lastIndexOf(".") + 1);
sBuilder.append(name3).append(",");
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder);
}
/**
* 反射出所有的字段
*/
System.out.println("-------------begin field list---------");
Field[] fields = clazzProxy1.getFields();
for (Field field : fields) {
if (field == null) {
System.out.println("Field is null");
break;
}
System.out.println(field.get(clazzProxy1));
}
/**
* 反射出所有的方法
*/
System.out.println("---------begin methods list---------");
// 测试动态代理类的所有方法
Method[] methods = clazzProxy1.getMethods();
for (Method method : methods) {
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for (Class clazzParam : clazzParams) {
/*
* String name2 = clazzParam.getName(); String name3
* =name2.substring(name2.lastIndexOf(".")+1);
*/
sBuilder.append(clazzParam.getName()).append(",");
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder);
}
System.out.println("---------begin create instance Object----");
// 创建动态代理的对象,使用字节码获取构造器
Constructor constructor = clazzProxy1
.getConstructor(InvocationHandler.class);
// 自定义了一个InvocationHandler的实现类
class myInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
System.out.println("——————————匿名内置类_______-");
Collection proxy1 = (Collection) constructor
.newInstance(new myInvocationHandler());
System.out.println(proxy1);
Collection proxy2 = (Collection) constructor
.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// TODO Auto-generated method stub
return null;
}
});
// 抽取方法
System.out.println("________Method Extract________");
final ArrayList target = new ArrayList();
Collection<String> proxy3 = (Collection<String>) getProxy(target,
new MyAdvice());
/**
* Client程序调用代理对象proxy3.add()设计三要素(代理对象,方法,参数)
*/
// 使用代理类调用目标的方法,会调用InvocationHandler对象的invoke方法
proxy3.add("wzm");
proxy3.add("zcz");
proxy3.add("zyz");
// proxy3.removeAll(proxy3);
System.out.println(proxy3.size());
}
private static Object getProxy(final Object target, final Advice advice) {
Object proxy3 = Proxy.newProxyInstance(target.getClass()
.getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
advice.beginMethod(method);
Object object = method.invoke(target, args);
if (args != null) {
for (Object arg : args) {
System.out.println("arg = " + arg);
}
}
advice.endMethod(method);
return object;
}
});
return proxy3;
}
}
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
package it.cast.day10.aopFramework;
import java.io.InputStream;
import java.util.Collection;
public class AopFrameworkTest {
/**
* @param args
*/
public static void main(String[] args) {
/**
* 直接用Class 加载资源
*/
//使用Class对象直接加载文件,返回值是流对象
InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
//AopFrameworkTest.class.getClassLoader().getResourceAsStream("config.properties");
Object bean = new BeanFactory(ips).getBean("xxx");
System.out.println(bean.getClass().getName());
((Collection)bean).clear();
}
}
BeanFactory————————————————————————————————————————————————————
package it.cast.day10.aopFramework;
import it.cast.day10.Advice;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
Properties pros = new Properties();
public BeanFactory(InputStream ips) {
try {
pros.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getBean(String name) {
//获取类名
String className = pros.getProperty(name);
Object bean = null;
try {
//获取类的Class对象
Class clazz = Class.forName(className);
//创建bean对象
bean = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
//判断,如果是代理,返回代理。不是代理就返回bean对象
if (bean instanceof ProxyFactoryBean) {
Object proxy = null;
try {
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean) bean;
Advice advice = (Advice) Class.forName(
pros.getProperty(name + ".advice")).newInstance();
// System.out.println(advice.getClass().getName());
//获取目标对象
Object target = Class.forName(
pros.getProperty(name + ".target")).newInstance();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
//获取代理对象
proxy = proxyFactoryBean.getProxy();
} catch (Exception e) {
e.printStackTrace();
}
//是代理对象就返回代理对象
return proxy;
}
return bean;
}
}
ProxyBeanFactory_______________________________________________________
package it.cast.day10.aopFramework;
import it.cast.day10.Advice;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactoryBean {
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Advice getAdvice() {
return advice;
}
public void setAdvice(Advice advice) {
this.advice = advice;
}
private Object target ;
private Advice advice;
//返回代理对象
public Object getProxy()
{
//动态代理
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().
getInterfaces(),
new InvocationHandler() {
//覆盖了InvocationHandler的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
advice.beginMethod(method);
//在这个方法中调用目标的方法
Object retVal = method.invoke(target, args);
advice.endMethod(method);
System.out.println(retVal);
return retVal;
}
}
);
return proxy;
}
}
配置文件
#xxx=java.util.ArrayList
xxx=it.cast.day10.aopFramework.ProxyFactoryBean
xxx.advice=it.cast.day10.MyAdvice
xxx.target=java.util.ArrayList