设计模式:计算机程序的设计总结 代码的编写 设计 为了提高代码的问题
-
1.解决资源共享问题 单例 工厂模式
-
2.代码的拓展问题 代理模式 装饰器模式 适配器模式
二次开发: -
3.解决依赖(对象)创建:工厂 建造者模式
-
代理模式:解决代码拓展问题 功能的增强/改变
代理人: 去做事的人
被代理人:委托代理人做事的人 -
代理类:
被代理类:
静态代理: 指代理类,对象都需要程序要手动编写代码
动态代理:代理类,对象都是由程序自动生成 不需要程序员手写代理类代码
静态代理:需要遵守以下条件
- 1.需要一个公共的接口
- 2…被代理类需要实现该接口
- 3.代理类也需要实现该接口
- 4.代理类必须保持一个被代理对象(被代理类的对象)
- 5.代理类中的方法必须调用被代理类中对应的方法
- 6.代理类中增强的代码需要在调用被代理类的方法的前后执行
静态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//静态代理
//1.公共接口
interface UserService{
public void addUser();
}
//2.被代理类
class UserServiceImpl implements UserService{
@Override
public void addUser() {
System.out.println("调用mapper执行sql");
}
}
//3.代理类
class UserServiceProxy implements UserService{
//4.保持一个被代理对象
private UserService userService;
public UserServiceProxy(UserService userService) {
super();
this.userService = userService;
}
@Override
public void addUser() {
//6.代理类中增强的代码需要在调用被代理类的方法的前后执行
System.out.println("开启事务");
//5.调用被代理对象的方法
try{
//代理类中的方法必须调用被代理类中对应的方法
userService.addUser();
System.out.println("提交事务");
}catch (Exception e){
e.printStackTrace();
System.out.println("回滚");
}
}
}
public class Test {
public static void main(String[] args) {
//创建代理类对象
UserService userService = new UserServiceProxy( new UserServiceImpl());
//使用
userService.addUser();
}
}
JDK实现动态代理
- JDK使用方法
- 1.需要一个公共的接口
- 2.被代理类需要实现该接口
- 3.创建一个代理类工厂
3.1.工厂需要保持一个被代理类对象
3.2.需要指定一个方法,该方法用来返回一个代理类对象
JDK代理生成的代理类是实现了被代理类上所有接口的子类,以下代码为例:
- 生成的$Proxy0类是OrderServiceImpl的代理类,该类实现了OrderService接口,当通过该类对象调用相关方法时,会自动调用InvocationHandler中的invoke方法,将代理类对象、要调用的方法及相关参数作为形参传递到invoke方法中来
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//JDK动态代理
// 接口
interface OrderService{
public boolean delOrder(int id);
}
// 被代理类
class OrderServiceImpl implements OrderService{
@Override
public boolean delOrder(int id) {
System.out.println("执行SQL:" + id);
return true;
}
}
// 代理类工厂
class ProxyFactory{
// 保持一个被代理类对象
private Object target;
public ProxyFactory(Object target) {
super();
this.target = target;
}
// 提供方法,返回代理类对象
public Object getProxy() {
// 调用API创建代理类对象
// 参数1:类加载器
// 参数2:被代理类实现的接口
// 参数3:调用处理器,编写增强的代码
return Proxy.newProxyInstance(
ProxyFactory.class.getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
// 参数1:代理类对象
// 参数2:即将被调用的方法
// 参数3:调用method方法的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-------------------");
System.out.println(proxy.getClass());
System.out.println(method.getName());
// for (Object arg : args) {
// System.out.println(arg);
// }
System.out.println("-------------------");
System.out.println("开启事务");
//调用被代理类对象的方法
Object result = method.invoke(target, args);
System.out.println("提交事务");
// 返回被代理类对象对应方法的返回值
return result;
}
});
}
}
public class Test{
public static void main(String[] args) {
// 创建被代理类对象
OrderService target = new OrderServiceImpl();
// 创建工厂
ProxyFactory factory = new ProxyFactory(target);
// 得到代理类对象
Object proxy = factory.getProxy();
System.out.println(proxy.getClass()); // $Proxy0 JDK代理生成的类
if (proxy instanceof OrderService) {
System.out.println("YES");
OrderService orderService = (OrderService)proxy;
//
System.out.println(orderService.delOrder(1002));
}
}
}`
CGLIB动态代理
cglib代理又称作子类代理
生成的类是被代理类的子类 自动生成一个代理类 该代理类继承了被代理类
只要代理类不是被final修饰 都可以通过cglib代理生成代理类,对象
- 1.需要非final修饰的代理类
- 2.创建一个工厂类,
2.1工厂类也需要保持一个代理类对象
2.2指定一个方法,该方法要返回代理类对象
------需要导入两个包
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
//CGLIB动态代理
class AddressServiceImpl{
public boolean address(String address){
System.out.println("添加地址");
return true;
}
}
//工厂
class CglibFactory{
//代理类对象
private Object target;
public CglibFactory(Object target) {
this.target = target;
}
//提供方法
public Object getProxy(){
//1.创建一个工具类对象
Enhancer enhancer = new Enhancer();
//2.设置代理类的父类
enhancer.setSuperclass(target.getClass());
//3.设置处理的方法
enhancer.setCallback(new MethodInterceptor() {
//参数
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务");
//调用被代理类的方法
Object result = method.invoke(target,args);
System.out.println("提交事务");
return result;
}
});
//创建代理类对象
return enhancer.create();
}
}
public class Test {
public static void main(String[] args) {
//1.创建被代理对象
AddressServiceImpl addressServiceImpl = new AddressServiceImpl();
//2.创建工厂
CglibFactory factory = new CglibFactory(addressServiceImpl);
//3.调方法创建代理类对象
Object proxy = factory.getProxy();
System.out.println(proxy.getClass());//$$EnhancerByCGLIB$$6b5f61aa CGLIB动态代理创建
if(proxy instanceof AddressServiceImpl){
System.out.println("YES");
addressServiceImpl = (AddressServiceImpl)proxy;
//调方法
addressServiceImpl.address("地球村");
}
}
}
JDK代理和CGLIB代理的区别
- 1.一个是JDK自带的 一个是第三方的
- 2.JDK代理要求被代理类必须实现接口 而CGLIB不需要
- 3.JDK代理生成的代理类是被代理类实现接口的子类。代理类需要需要实现这些接口, 而CGLIB生成的代理是被代理类的子类,代理类直接继承被代理类