准备工作
创建接口
package com.itheima.service;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy(proxyTargetClass = true)
public interface UserService {
public void save();
}
实现类
package com.itheima.service.impl;
import com.itheima.service.UserService;
public class UserServiceImpl implements UserService{
public void save() {
System.out.println("水泥墙");
}
}
静态代理
代理
package base.decorator;
import com.itheima.service.UserService;
/**
* 静态代理 3步曲
* 代理对象:UserService
* 1.首先实现该接口
* 2.构造方法载入代理对象
* 3.实现代理对象的方法=>添加增强功能
*/
public class UserServiceImplDecorator implements UserService {
private UserService userService;
public UserServiceImplDecorator(UserService userService){
this.userService = userService;
}
public void save() {
//原始调用
userService.save();
//增强功能(后置)
System.out.println("刮大白");
}
}
调用
package base.decorator;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
public class App {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService userService1 = new UserServiceImplDecorator(userService);
userService1.save();
}
}
运行结果
动态代理 jdk Proxy
package base.cglib;
import com.itheima.service.UserService;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* CGLIB代理
*/
public class UserServiceCglibProxy {
public static UserService createUserServiceCglibProxy(Class clazz) {
//创建Enhancer对象(可以理解为内存中动态创建了一个类的字节码)
Enhancer enhancer = new Enhancer();
//设置Enhancer对象的父类是指定类型UserServerImpl
enhancer.setSuperclass(clazz);
//设置回调方法
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//通过调用父类的方法实现对原始方法的调用
Object ret = methodProxy.invokeSuper(o, args);
//后置增强内容,与JDKProxy区别:JDKProxy仅对接口方法做增强,cglib对所有方法做增强,包括Object类中的方法.
//如果想对某个方法增强,需要筛选,如下
if (method.getName().equals("save")) {
System.out.println("CGLIB代理 ==>仅对save方法");
}
System.out.println("CGLIB代理 ==>增强所有方法");
return ret;
}
});
//使用Enhancer对象创建对应的对象
return (UserService) enhancer.create();
}
}
应用
package base.cglib;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
public class App {
public static void main(String[] args) {
UserService userService = UserServiceCglibProxy.createUserServiceCglibProxy(UserServiceImpl.class);
System.out.println("---------测试sava方法-------------");
userService.save();
System.out.println("----------测试userService的非sava方法----------");
userService.hashCode();
}
}
运行
动态代理 CGLIB
package base.cglib;
import com.itheima.service.UserService;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* CGLIB代理
*/
public class UserServiceCglibProxy {
public static UserService createUserServiceCglibProxy(Class clazz) {
//创建Enhancer对象(可以理解为内存中动态创建了一个类的字节码)
Enhancer enhancer = new Enhancer();
//设置Enhancer对象的父类是指定类型UserServerImpl
enhancer.setSuperclass(clazz);
//设置回调方法
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//通过调用父类的方法实现对原始方法的调用
Object ret = methodProxy.invokeSuper(o, args);
//后置增强内容,与JDKProxy区别:JDKProxy仅对接口方法做增强,cglib对所有方法做增强,包括Object类中的方法.
//如果想对某个方法增强,需要筛选,如下
if (method.getName().equals("save")) {
System.out.println("CGLIB代理 :仅对save方法");
}
System.out.println("CGLIB代理 : 增强所有方法");
return ret;
}
});
//使用Enhancer对象创建对应的对象
return (UserService) enhancer.create();
}
}
应用
package base.cglib;
import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;
public class App {
public static void main(String[] args) {
UserService userService = UserServiceCglibProxy.createUserServiceCglibProxy(UserServiceImpl.class);
System.out.println("---------测试sava方法-------------");
userService.save();
System.out.println("----------测试userService的非sava方法----------");
userService.hashCode();
}
}
运行