java 静态代理和动态代理
代理:就是用代理类实现委托类的一些功能和附加的预处理功能(包括消息过滤,日志等)。
java的代理分为静态代理和动态代理。动态代理又有jdk代理和cglib代理。静态代理分为继承超类代理和接口代理(名称不重要下面会详细介绍)。
在详细介绍之前先介绍一下静态代理和动态代理的区别:
静态代理的时候代理类要实现被代理接口的所有的方法。
动态代理是利用java反射机制,代理类只需要实现InvocationHandler接口即可,无需实现接口所有方法,在扩展和代码优化上有明显优势。
第一:静态代理
在java里只有实现接口或者继承父类才可以实现对其功能,也就是根据这一点静态代理可以分为继承代理和接口代理。
1,继承代理
由于代理的功能一般最好没有实现,否则代理就没有价值了,所以被代理类(委托类)最好是abstract,也就出现了继承代理。
//抽象类
public abstract class UserDao { public abstract void userAdd(); public abstract void userDelete();}//userDao 第一个实现类public class UserDaoDB2Impl extends UserDao {@Overridepublic void userAdd() {System.out.println("insert user data into db2 datebase!");}@Overridepublic void userDelete() {System.out.println("delete user data from db2 datebase!");}}//userDao 第二个实现类public class UserDaoMysqlImpl extends UserDao {@Overridepublic void userAdd() {System.out.println("insert user data into mysql datebase!");}@Overridepublic void userDelete() {System.out.println("delete user data from mysql datebase!");}}//userDao 代理类public class UserDaoProxy extends UserDao { UserDao dao;public UserDaoProxy(UserDao d){this.dao=d;}@Overridepublic void userAdd() {dao.userAdd();}@Overridepublic void userDelete() {dao.userDelete();} }//测试类public class UserDaoTest {/** * @param args */public static void main(String[] args) {UserDao mysqldao=new UserDaoMysqlImpl();UserDao db2dao=new UserDaoDB2Impl();UserDaoProxy p=new UserDaoProxy(mysqldao);//UserDaoProxy p=new UserDaoProxy(db2dao);p.userAdd();}} 2,接口代理
这个代理是大家很熟悉的,也是很多人都用过的,就是通过实现接口的方式实现代理,代码如下:
//接口public interface AdminDao { public void adminAdd(); public void adminDel(); }// 第一种DB2 实现类public class AdminDaoDB2Impl implements AdminDao {@Overridepublic void adminAdd() {System.out.println("insert admin data into DB2 database!");} @Overridepublic void adminDel() {System.out.println("delete admin data from DB2 database!");}}//第二种oracle 实现类public class AdminDaoOracleImpl implements AdminDao {@Overridepublic void adminAdd() {System.out.println("insert admin data into oracle database!");} @Overridepublic void adminDel() {System.out.println("delete admin data from oracle database!");}}//AdminDao 代理类public class AdminDaoProxy implements AdminDao {AdminDao dao;public AdminDaoProxy(AdminDao dao){this.dao=dao;}@Overridepublic void adminAdd() { dao.adminAdd();} @Overridepublic void adminDel() {dao.adminDel();} }// 静态代理测试类public class AdminTest { public static void main(String arg[]){ AdminDao db2Dao=new AdminDaoDB2Impl(); AdminDao oracleDao=new AdminDaoOracleImpl(); AdminDaoProxy proxy_1=new AdminDaoProxy(db2Dao); proxy_1.adminAdd(); AdminDaoProxy proxy_2=new AdminDaoProxy(oracleDao); proxy_2.adminAdd(); }} 第二:动态代理
动态代理是利用java反射机制,代理类通过实现InvocationHandler接口来完成对委托类功能的实现,其实里面是jdk对java的部分代码进行了封装,在实现InvocationHandler接口的时候,需要实现invoke方法,而invoke方法里需要传进2个必要参数代理类和Method,其中method里的invoke方法就可以去实现委托类里所有的接口,因为有了这层封装所以代理类不需要在继承或实现被代理类也可以实现代理功能。
//接口public interface AdminDao {public void adminAdd(); public void adminDel();}//第一种 DB2 实现类public class AdminDaoDB2Impl implements AdminDao {@Overridepublic void adminAdd() {System.out.println("insert admin data into DB2 database!");} @Overridepublic void adminDel() {System.out.println("delete admin data from DB2 database!");}}//第二种oracle 实现类public class AdminDaoOracleImpl implements AdminDao {@Overridepublic void adminAdd() {System.out.println("insert admin data into oracle database!");} @Overridepublic void adminDel() {System.out.println("delete admin data from oracle database!");}}//动态代理实现类public class AdminDaoDynamicProxy implements InvocationHandler {AdminDao admindao;public AdminDaoDynamicProxy(AdminDao d){this.admindao=d;}@Overridepublic Object invoke(Object proxy, Method method, Object[] arg2)throws Throwable {System.out.println("before---");Object obj=method.invoke(admindao, arg2);System.out.println("after----");return obj;}}//测试类public class AdminDynamicTest {public static void main(String[] args) {AdminDao db2dao=new AdminDaoDB2Impl();AdminDaoDynamicProxy proxy=new AdminDaoDynamicProxy(db2dao);//创建动态代理实例(也可以通过另一种方法实现)AdminDao dao=(AdminDao)Proxy.newProxyInstance(AdminDao.class.getClassLoader(), new Class[]{AdminDao.class},proxy); dao.adminAdd();}}备注:代理类里可以实现一些辅助功能,我没有添加,这个需要的时候可以加进去,在此省略。