转眼间工作一年多了,感觉技术没有什么提升,只是对开发工具熟悉了一些,对复制粘贴熟悉了一些,可是对程序的了解还是停留在入职前。可能是平时不喜欢钻研,只要把工作完成好就行了,至于为什么这样做,很少去考虑。平时自己利用休息时间自学的时候也是三天打鱼两天晒网,而且很少自己动手做,这样很快就忘光了,跟没学没两样。有一个同事跟我差不多一起入职的,已经辞职一个星期了,面试了十几家公司,面试官问的很多技术问题,他只是知道,面试官深入去问的时候,就一概不知了。他把大多面试官问的问题都告诉我了,结果我发现自己也是什么都不知道,突然感觉好迷茫,什么程序员工作两年后工资就翻倍,什么月薪10k以上,感觉像我现在的状态别说两年后了,就是五年后工资翻倍都是问题。因此,在此立个flag,以后每周要写一篇博客来记录学习的笔记。鄙人从小语文就差,因此在语言组织方面有缺陷,希望大家谅解。这是我的第一个博客笔记,原谅我前面的废话,如果笔记中有错误希望博友能够直接留言指出,在此谢谢各位博友了。下面谈谈java中的代理
代理是一种设计模式,可以通过代理对象来访问目标对象。这样可以在访问目标对象的方法前后,增加额外的功能操作。扩展了目标对象的功能。
一、静态代理
优点:静态代理可以在不修改目标对象功能的前提下,对目标对象功能进行扩展。
缺点:代理对象与目标对象实现一样的接口,因此要写很多代理类,而且一旦接口增加了方法,代理对象和目标对象都要去实现,维护麻烦。样的接口
package test.proxy_static;
/**
* 目标对象类
* @author Shepherd
*
*/
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("执行目标对象save方法");//业务方法
}
}
package test.proxy_static;
/**
* 目标对象实现的接口
* @author Shepherd
*
*/
public interface IUserDao {
public void save();
}
package test.proxy_static;
/**
* 代理对象类(需要实现目标对象一样的接口)
* @author Shepherd
*
*/
public class UserDaoProxy implements IUserDao{
private IUserDao target; //代理对象中维护的目标对象
public UserDaoProxy(IUserDao userDao) {
this.target = userDao;
}
@Override
public void save() {
System.out.println("执行目标对象前");
target.save(); //实际执行的是目标对象中的save()方法
System.out.println("执行目标对象后");
}
}
package test.proxy_static;
/**
* 测试程序
* @author Shepherd
*
*/
public class App {
public static void main(String[] args) {
UserDao userDao = new UserDao(); //创建目标对象
IUserDao userDaoProxy = new UserDaoProxy(userDao);//创建代理对象,里面维护一个目标对象
userDaoProxy.save(); //执行代理对象的save()方法
}
}
/*以下是输出结果:
执行目标对象前
执行目标对象save方法
执行目标对象后*/
二、动态代理中的jdk代理
代理对象的创建是利用jdk的api,动态在在内存中构建代理对象。
优点:代理对象是由jdk动态构建,可以代理不同类型的目标对象,不需要引用第三方jar包
缺点:目标对象也必须实现接口,否则不能代理
目标对象及其实现的接口与静态代理一样,下面是利用jdk代理创建代理工厂
package test.proxy_static;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* jdk代理工厂类
* @author Shepherd
*
*/
public class JDKProxyFactory {
private Object target; //维护的目标对象
public JDKProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance(){ //返回代理对象实例
return Proxy.newProxyInstance(target.getClass().getClassLoader(), //当前目标对象的类加载器
target.getClass().getInterfaces(), //当前目标对象实现的接口类型
new InvocationHandler() { //事件处理器
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行目标对象前");
Object returnValue = method.invoke(target, args);
System.out.println("执行目标对象后");
return returnValue;
}
});
}
}
package test.proxy_static;
/**
* 测试程序
* @author Shepherd
*
*/
public class App {
public static void main(String[] args) {
UserDao userDao = new UserDao(); //创建目标对象
System.out.println("目标对象:"+userDao.getClass());//输出目标对象的类型
JDKProxyFactory proxyFactory = new JDKProxyFactory(userDao);
IUserDao userDaoProxy = (IUserDao) proxyFactory.getProxyInstance();//利用代理工厂创建一个代理对象
System.out.println("代理对象:"+userDaoProxy.getClass());//输出代理对象的类型
userDaoProxy.save(); //执行代理对象的save()方法
}
}
/*以下是输出结果:
目标对象:class test.proxy_static.UserDao
代理对象:class com.sun.proxy.$Proxy0
执行目标对象前
执行目标对象save方法
执行目标对象后
*/
三、cglib动态代理
Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。
优点:代理对象不需要实现目标对象实现的接口,目标对象也可以不实现接口
缺点:需要引用第三方cglib-*.jar包
package test.proxy_cglib;
/**
* 需要代理的目标对象类
* @author Shepherd
*/
public class UserDao {
public void save() {
System.out.println("执行目标对象save方法");
}
}
package test.proxy_cglib;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/**
* cglib代理工厂
* @author Shepherd
*/
public class CglibProxyFactory implements MethodInterceptor{ //代理工厂类需实现MethodInterceptor接口
private Object target; //工厂类里维护的目标对象
public CglibProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance(){ //返回子类代理对象
Enhancer en = new Enhancer(); //创建子类代理的工具类
en.setSuperclass(target.getClass());//指定该代理对象的父类
en.setCallback(this); //设置回掉函数
return en.create(); //创建子类代理对象
}
@Override
public Object intercept(Object obj, Method method, Object[] arg2, MethodProxy arg3)
throws Throwable {
System.out.println("执行目标方法前");
Object returnValue = method.invoke(target, arg2);
System.out.println("执行目标方法后");
return returnValue;
}
}
/**
* 主程序
* @author Shepherd
*/
public class App {
public static void main(String[] args) {
UserDao userDao = new UserDao();
System.out.println("目标对象:"+userDao.getClass());
CglibProxyFactory proxyFactory = new CglibProxyFactory(userDao);//创建cglib代理工厂
//因为子类代理继承了目标对象,所以可以用目标对象类型接收
UserDao proxyInstance = (UserDao) proxyFactory.getProxyInstance();//利用代理工厂创建子类代理对象
System.out.println("cglib代理对象:"+proxyInstance.getClass());//输出cglib代理对象类型
proxyInstance.save();
}
}
/*以下是输出结果:
目标对象:class test.proxy_cglib.UserDao
cglib代理对象:class test.proxy_cglib.UserDao$$EnhancerByCGLIB$$9373ca85
执行目标方法前
执行目标对象save方法
执行目标方法后
*/