静态代理
package senssic.demo;
/**
* 静态代理
*
* @author Administrator
*
*/
interface AFace {// 接口
public void say();
}
class BClass implements AFace {// 实际类
@Override
public void say() {
System.out.println("hello word!");
}
}
class PBClass implements AFace {// 代理类
private final BClass bClass;
public PBClass(BClass bClass) {
this.bClass = bClass;
}
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("运行实际类方法前可发生的事情…………");
this.bClass.say();
System.out.println("运行实际类方法后可发生的事情…………");
}
}
public class PoxyClass {
public static void main(String[] args) {
AFace aFace = new PBClass(new BClass());
aFace.say();
}
}
缺点:
一个代理类只能为一个接口服务,所以我们接下来使用动态代理
jdk的动态
package senssic.demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理
*
* @param args
*/
interface BFace {// 接口
public void say();
}
class BClass implements BFace {// 真实类
@Override
public void say() {
System.out.println("hello word!");
}
}
class DPClass implements InvocationHandler {// 动态代理类必须实现InvocationHandler接口并实现invoke方法确定实现的类
private Object object;
public Object bind(Object object) {
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(),
object.getClass().getInterfaces(), this);// 使用反射代理类Proxy实例化代理的接口(必须绑定接口),如果想代理没有接口的类需要使用cglib包
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)// 调用对应的方法
throws Throwable {
System.out.println("运行实际类方法前可发生的事情…………");
Object temp = method.invoke(this.object, args);
System.out.println("运行实际类方法后可发生的事情…………");
return temp;
}
}
public class DPoxyClass {
public static void main(String[] args) {
BFace bFace = (BFace) new DPClass().bind(new BClass());
bFace.say();
}
}
优点:可以动态的代理,不限于接口的类型
缺点:必须绑定接口,即代理的类必须要实现接口,如果代理未实现接口的类我们需要apache的cglib包外包的动态代理
下载地址:
http://cglib.sourceforge.net/
package senssic.demo;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class CClass {// 实际类
public void say() {
System.out.println("hello word!");
}
}
class CPlass implements MethodInterceptor {// 代理类,必须实现MenthodInterceptor接口通过反射调用实际方法
private Object object;
public Object bind(Object object) {// 绑定操作设置对应的实际类
this.object = object;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.object.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] objects,
MethodProxy proxy) throws Throwable {
System.out.println("运行实际类方法前可发生的事情…………");
Object temp = proxy.invokeSuper(obj, objects);// 反射调用实际类方法
System.out.println("运行实际类方法后可发生的事情…………");
return temp;
}
}
public class CPClass {
public static void main(String[] args) {
CPlass cPlass = new CPlass();
CClass cClass = (CClass) cPlass.bind(new CClass());
cClass.say();
}
}
Cglib动态代理 JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
仿spring原理的实现
package senssic.demo;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Properties;
interface DFace {//实际类接口
public void say();
}
class DClass implements DFace {//实际类,因为是jdk动态代理所以必须有实现接口
@Override
public void say() {
System.out.println("hello word!");
}
}
class BeanFactory {// bean工厂
Properties pros = new Properties();
public BeanFactory(InputStream ips) {
try {
pros.load(ips);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object getBean(String name) {
String className = pros.getProperty(name);
Class cla = null;
Object bean = null;
try {
cla = Class.forName(className);
bean = cla.newInstance();
if (bean instanceof ProxyFactoryBean) {
ProxyFactoryBean pFactoryBean = (ProxyFactoryBean) bean;
Adivce advice = (Adivce) Class.forName(
pros.getProperty(name + ".advice")).newInstance();
Object target = Class.forName(
pros.getProperty(name + ".target")).newInstance();
pFactoryBean.setAdvice(advice);
pFactoryBean.setTarget(target);
Object proxy = pFactoryBean.getProxy();
return proxy;
}
} catch (Exception e) {
// TODO: handle exception
}
return bean;
}
}
class ProxyFactoryBean {//业务处理类
private Adivce advice;
private Object target;
public Adivce getAdvice() {
return advice;
}
public void setAdvice(Adivce advice) {
this.advice = advice;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {
Object temp = Proxy.newProxyInstance(
target.getClass().getClassLoader(), target.getClass()
.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object obj, Method method,
Object[] objects) throws Throwable {
advice.before();
Object object = method.invoke(target, objects);
advice.after();
return object;
}
});
return temp;
}
}
class Adivce {
public void before() {
System.out.println("运行实际类方法前可发生的事情…………");
}
public void after() {
System.out.println("运行实际类方法后可发生的事情…………");
}
}
public class SClass {
public static void main(String[] args) {
InputStream ips = SClass.class.getResourceAsStream("config.properties");
DFace bean = (DFace) new BeanFactory(ips).getBean("xxx");//动态代理类只能被转换为对应的接口,不能转换为实现类
bean.say();
}
}
配置文件为:在同一目录下,文件名:config.properties
#xxx=java.util.ArrayList
xxx=senssic.demo.ProxyFactoryBean
xxx.advice=senssic.demo.Adivce
xxx.target=senssic.demo.DClass
运行结果:
xxx=senssic.demo.ProxyFactoryBean
xxx.advice=senssic.demo.Adivce
xxx.target=senssic.demo.DClass
运行实际类方法前可发生的事情…………
hello word!
运行实际类方法后可发生的事情…………
hello word!
运行实际类方法后可发生的事情…………