程序中的代理
安全 事务 日志
StudentService ------|----------|------------|-------------
CourseService ------|----------|------------|-------------
MiscService ------|----------|------------|-------------
method1 method2 method3
{ { {
------------------------------------------------------切面
.... .... ......
------------------------------------------------------切面
} } }
------------------------------------------------------切面
func1 func2 func3
{ { {
.... .... ......
} } }
------------------------------------------------------切面
package AsbstractFactory;
import java.lang.reflect.Constructor;
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 {
public static void main(String[] args) throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
// 1.创建实现了Collection接口的动态类和查看其名称,分析Proxy.getProxyClass方法的各个参数,获得代理类的字节码。
Class clazz = Proxy.getProxyClass(ProxyTest.class.getClassLoader(), Collection.class);
System.out.println(clazz.getName());
// 2.通过反射获得代理类的方法
Method[] methods = clazz.getMethods();
for (Method m : methods) {
System.out.println(m.getName());
}
System.out.println("---------------------");
// 3.用反射获得构造方法
Constructor[] contructors = clazz.getConstructors();
// 创建动态类的实例对象
// clazz.newInstance();
// clazz.getConstructor().newInstance();
// 4.通过反射获得对应的构造函数
Constructor constructor = clazz.getConstructor(InvocationHandler.class);
// 编写一个最简单的InvocationHandler类
Collection proxy = (Collection) constructor.newInstance(new InvocationHandler() {
//实现了接口的要被代理的对象
ArrayList target = new ArrayList();
@Override
// 这里的三个参数正好就是proxy.add(obj)中的三部分 。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object tObject = invoke(target, method, args);
return tObject;
}
});
proxy.size();
}
}
import java.lang.reflect.Method;
//通知接口
public interface Advice {
void beforeMethod(Method method);
void afterMethod(Method method);
}
import java.lang.reflect.Method;
//通知接口实现类
public class MyAdvice implements Advice {
long beginTime = 0;
public void afterMethod(Method method) {
// TODO Auto-generated method stub
System.out.println("从传智播客毕业上班啦!");
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of " + (endTime - beginTime));
}
public void beforeMethod(Method method) {
// TODO Auto-generated method stub
System.out.println("到传智播客来学习啦!");
beginTime = System.currentTimeMillis();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyTest {
/**
* @param args
*/
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception {
// 1.被代理类
ArrayList target = new ArrayList();
// 切入的通知功能
Advice advice = new MyAdvice();
// 给到代理类对象
Collection proxy = (Collection) getProxy(target, advice);
System.out.println(proxy.isEmpty());
}
private static Object getProxy(final Object target, final Advice advice) {
Object proxy3 = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,
// 还可以在代理方法中的如下四个位置加上系统功能代码:
// 1.在调用目标方法之前
// 2.在调用目标方法之后
// 3.在调用目标方法前后
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
});
return proxy3;
}
}
#xxx=java.util.ArrayList
xxx=cn.itcast.ProxyFactoryBean
xxx.target=java.util.ArrayList
xxx.advice=cn.itcast.MyAdvice
import java.io.InputStream;
import java.util.Collection;
public class AopFrameworkTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//读取配置文件
InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
//
Object bean = new BeanFactory(ips).getBean("xxx");
System.out.println(bean.getClass().getName());
((Collection)bean).clear();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//工厂类BeanFactory负责创建目标类或代理类的实例对象,
//并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,
//如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,
//否则,返回该类实例对象的getProxy方法返回的对象。
public class BeanFactory {
//读取Properties的key-value值
Properties props = new Properties();
public BeanFactory(InputStream ips){
try {
props.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
}
//getBean方法根据参数字符串返回一个相应的实例对象,
//如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,
//否则,返回该类实例对象的getProxy方法返回的对象。
public Object getBean(String name){
String className = props.getProperty(name);
Object bean = null;
try {
Class clazz = Class.forName(className);
bean = clazz.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(bean instanceof ProxyFactoryBean){
Object proxy = null;
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;
try {
Advice advice = (Advice)Class.forName(props.getProperty(name + ".advice")).newInstance();
Object target = Class.forName(props.getProperty(name + ".target")).newInstance();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
proxy = proxyFactoryBean.getProxy();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return proxy;
}
return bean;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.itcast.day3.Advice;
public class ProxyFactoryBean {
private Advice advice;
private Object target;
public Advice getAdvice() {
return advice;
}
public void setAdvice(Advice advice) {
this.advice = advice;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//添加通知
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
}
);
return proxy3;
}
}