使用静态代理时,需要定义接口或者父类,被代理对象和代理对象一起实现相同的接口或者是继承相同的父类
/***
* @author shaofan
* @Description 静态代理
*/
public class StaticProxy {
public static void main(String[] args) {
ITeacherDao proxy = new TeacherDaoProxy(new TeacherDao());
proxy.teach();
}
}
interface ITeacherDao{
void teach();
}
class TeacherDao implements ITeacherDao{
@Override
public void teach() {
System.out.println("teaching");
}
}
class TeacherDaoProxy implements ITeacherDao{
private ITeacherDao target;
public TeacherDaoProxy(ITeacherDao target){
this.target = target;
}
@Override
public void teach() {
System.out.println("preparing");
target.teach();
System.out.println("finished");
}
}
/***
* @author shaofan
* @Description JDK动态代理
*/
public class JdkDynamicProxy {
public static void main(String[] args) {
ITeacherDao proxy = (ITeacherDao) ProxyFactory.getProxyInstance(new TeacherDao());
proxy.teach();
}
}
interface ITeacherDao{
void teach();
}
class ProxyFactory{
/**
* 获取代理对象
* @param target 需要代理的目标对象
* @return
*/
static Object getProxyInstance(Object target){
// 通过jdk中的Proxy类下的newProxyInstance方法,使用目标对象的类加载器、接口来动态创建一个目标接口类型的代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> {
System.out.println("preparing");
Object obj = method.invoke(target,args);//切忌传入proxy,这里要传入需要执行方法的对象,应该是target
System.out.println("finished");
return obj;
});
}
}
class TeacherDao implements ITeacherDao{
@Override
public void teach() {
System.out.println("teaching");
}
}
/***
* @author shaofan
* @Description Cglib动态代理
*/
public class CglibProxy {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new TeacherDao());
TeacherDao proxy = (TeacherDao) factory.getProxyInstance();
proxy.teach();
}
}
class ProxyFactory implements MethodInterceptor{
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
public void setTarget(Object target){
this.target = target;
}
public Object getProxyInstance(){
// 创建一个增强对象创键者
Enhancer enhancer = new Enhancer();
// 设置增强对象继承的父类
enhancer.setSuperclass(target.getClass());
// 设置调用方法时的回调,设置为自身,因为自身继承了MethodInterceptor接口,会调用intercept方法
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("preparing");
Object obj = method.invoke(target,objects);
System.out.println("finished");
return obj;
}
}
class TeacherDao{
public void teach(){
System.out.println("teaching");
}
}