提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
package jdk_dynamic_proxy.with_target_impl; public interface IUserDao { void saveUser(); void sayHello(); String returnValue(); }
package jdk_dynamic_proxy.with_target_impl; public class UserDaoImpl implements IUserDao { @Override public void saveUser() { System.out.println("保存用户________"); } @Override public void sayHello() { System.out.println("hello world!"); } @Override public String returnValue() { return "I am return value."; } }
/** * 代理有实现类的target */ public class ProxyFactory { private Object target; public ProxyFactory(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 { // 当一个接口有多个方法时,此时可以通过method.getName()来判断是哪个方法,从而实现不同的代理逻辑 if (method.getName().equals("sayHello")) { System.out.println("sayHello前_______"); method.invoke(target, args); System.out.println("sayHello后_______"); } else if (method.getName().equals("saveUser")) { System.out.println("saveUser前_______"); method.invoke(target, args); System.out.println("saveUser后_______"); // 动态代理可以修改除了前后增强外,还可以修改原有方法的返回值,利用这个特性可以在过滤器中修改编码,从而纠正中文乱码 } else if (method.getName().equals("returnValue")) { return "I am return value.-->> I am proxy return value."; } return null; } }); } }
public class Main { public static void main(String[] args) { IUserDao userDaoProxy = (IUserDao) new ProxyFactory(new UserDaoImpl()).getProxyInstance(); userDaoProxy.saveUser(); userDaoProxy.sayHello(); System.out.println(userDaoProxy.returnValue()); } }
mybatis的mapper接口,还有dubbo的rpc调用使用的就是这种情况。
public interface IUserDao { void saveUser(); }
public class ProxyFactoryWithoutTargetImpl { private Class target; public ProxyFactoryWithoutTargetImpl(Class target) { this.target = target; } public Object getProxyInstance() { return Proxy.newProxyInstance(target.getClassLoader(), new Class[]{target}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我仅仅代理了一个接口的方法,而没有代理有具体实现类的方法"); return null; } }); } }
public class Main { public static void main(String[] args) { IUserDao userDaoProxy = (IUserDao)new ProxyFactoryWithoutTargetImpl(IUserDao.class).getProxyInstance(); userDaoProxy.saveUser(); } }
Mybaits 源码解析 (五)----- Mapper接口底层原理(为什么Mapper不用写实现类就能访问到数据库?)
为啥mybatis的mapper只有接口没有实现类,但它却能工作?
描述Java动态代理的几种实现方式,分别说出相应的优缺点。