大家好,欢迎来到IT知识分享网。
一、代理模式的作用
- 功能增强: 基于某个功能,再增加一些功能。
(比如目标类只负责核心功能,其他附属功能通过代理类完成。代理类的方法名与目标类的方法相同,内容不同,在核心功能外加了一些额外逻辑) - 控制访问: 防止直接访问目标。
二、实现代理的方式
2.1 动态代理:
特点:
在程序执行过程中,自动使用jdk反射机制创建代理对象(而不需要写.java源文件),并且动态指定要代理的目标类。
优点:
缺点
2.2 静态代理:
特点:
代理类是自己手动实现的。自己创建一个类作为代理类要代理的目标类是确定的。
优点:
缺点:
三、动态代理的实现
jdk动态代理
基于接口实现代理
3.1 创建目标接口
public interface Star {
String sing(String name); void dance(); }
3.2 创建目标类实现目标接口
public class BigStar implements Star {
private String name; public BigStar(String name) {
this.name = name; } public String sing(String name) {
System.out.println(this.name + "正在唱歌儿:" + name); return "谢谢儿!谢谢儿!"; } public void dance() {
System.out.println(this.name + "正在跳舞儿"); } }
3.3 创建代理工具
public class ProxyUtil {
public static Star createProxy(BigStar bigStar) {
/*newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 参数1:用于指定一个类加载器 参数2:指定生成的代理长什么样子,也就是有哪些方法 参数3:用来指定生成的代理对象要干什么事情 */ // Star starProxy = ProxyUtil.createProxy(s); // starProxy.sing("好日子") starProxy.dance() Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{
Star.class}, new InvocationHandler() {
@Override //回调方法:当主程序执行sing方法时会调用invoke,并将参数传过来 // proxy就是代理对象starProxy,method指sing,args指"好日子" public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理对象要做的事情,会在这里写代码 if (method.getName().equals("sing")) {
System.out.println("准备话筒,收钱20万"); } else if (method.getName().equals("dance")) {
System.out.println("准备场地,收钱1000万"); } return method.invoke(bigStar, args); } }); return starProxy; } }
3.4 测试调用
public class Test {
public static void main(String[] args) {
BigStar s = new BigStar("杨超越"); Star starProxy = ProxyUtil.createProxy(s); String rs = starProxy.sing("好日子"); System.out.println(rs); starProxy.dance(); } }
3.5 运行结果:
3.6 执行逻辑:
四、案例-使用代理优化用户管理类
场景
- 某系统有一一个用户管理类,包含用户登录,删除用户,查询用户等功能,系统要求统
计每个功能的执行耗时情况,以便后期观察程序性能。
需求
- 现在,某个初级程序员已经开发好了该模块,请观察该模块的代码,找出目前存在的
问题,并对其进行改造。
/ * 用户业务接口 */ public interface UserService {
//登录功能 void login(String loginName, String passWord) throws InterruptedException; //删除用户 void deleteUsers() throws InterruptedException; //查询用户,返回数组的形式 String[] selectUsers() throws InterruptedException; }
/ * 用户业务实现类(面向接口编程) */ public class UserServiceImpl implements UserService {
@Override public void login(String loginName, String passWord) throws InterruptedException {
long startTime = System.currentTimeMillis(); if ("admin".equals(loginName) && "".equals(passWord)) {
System.out.println("您登录成功,欢迎光临本系统~"); } else {
System.out.println("您登录失败,用户名或密码错误~"); } Thread.sleep(1000); long endTime = System.currentTimeMillis(); System.out.println("login方法执行耗时:" + (endTime - startTime) / 1000.0 + "s"); } @Override public void deleteUsers() throws InterruptedException {
long startTime = System.currentTimeMillis(); System.out.println("成功删除了1万个用户"); Thread.sleep(1500); long endTime = System.currentTimeMillis(); System.out.println("deleteUsers方法执行耗时:" + (endTime - startTime) / 1000.0 + "s"); } @Override public String[] selectUsers() throws InterruptedException {
long startTime = System.currentTimeMillis(); System.out.println("查询出了3个用户"); String[] names = {
"金庸", "莫言", "南派三叔"}; Thread.sleep(500); long endTime = System.currentTimeMillis(); System.out.println("selectUsers方法执行耗时:" + (endTime - startTime) / 1000.0 + "s"); return names; } }
/ * 目标: 使用动态代理解决实际问题,并掌握使用代理的好处。 */ public class Test {
public static void main(String[] args) throws Exception {
//1、创建用户业务对象 UserService userService = new UserServiceImpl(); //2、调用用户业务的功能 userService.login("admin", ""); System.out.println("--------------------------------------"); userService.deleteUsers(); System.out.println("--------------------------------------"); String[] names = userService.selectUsers(); System.out.println("查询到的用户是:" + names); System.out.println("--------------------------------------"); } }
public class ProxyUtil {
public static UserService createProxy(UserService userService) {
/*newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 参数1:用于指定一个类加载器 参数2:指定生成的代理长什么样子,也就是有哪些方法 参数3:用来指定生成的代理对象要干什么事情 */ // Star starProxy = ProxyUtil.createProxy(s); // starProxy.sing("好日子") starProxy.dance() UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{
UserService.class}, new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理对象要做的事情,会在这里写代码 if (method.getName().equals("login") || method.getName().equals("deleteUsers") || method.getName().equals("selectUsers")) {
long startTime = System.currentTimeMillis(); Object rs = method.invoke(userService, args); long endTime = System.currentTimeMillis(); System.out.println(method.getName() + "方法执行耗时:" + (endTime - startTime) / 1000.0 + "s"); return rs; } else {
Object rs = method.invoke(userService, args); return rs; } } }); return userServiceProxy; } }
修改UserServiceImpl
/ * 用户业务实现类(面向接口编程) */ public class UserServiceImpl implements UserService {
@Override public void login(String loginName, String passWord) throws InterruptedException {
if ("admin".equals(loginName) && "".equals(passWord)) {
System.out.println("您登录成功,欢迎光临本系统~"); } else {
System.out.println("您登录失败,用户名或密码错误~"); } Thread.sleep(1000); } @Override public void deleteUsers() throws InterruptedException {
System.out.println("成功删除了1万个用户"); } @Override public String[] selectUsers() throws InterruptedException {
System.out.println("查询出了3个用户"); String[] names = {
"金庸", "莫言", "南派三叔"}; Thread.sleep(500); return names; } }
/ * 目标: 使用动态代理解决实际问题,并掌握使用代理的好处。 */ public class Test {
public static void main(String[] args) throws Exception {
//1、创建用户业务对象 UserService userService = (UserService)ProxyUtil.createProxy(new UserServiceImpl()); //2、调用用户业务的功能 userService.login("admin", ""); System.out.println("--------------------------------------"); userService.deleteUsers(); System.out.println("--------------------------------------"); String[] names = userService.selectUsers(); System.out.println("查询到的用户是:" + Arrays.toString(names)); System.out.println("--------------------------------------"); } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/119239.html



