代码拉取完成,页面将自动刷新
Proxy类和InvocationHandler接口
import com.example.proxy.service.OrderService;
import com.example.proxy.service.impl.OrderServiceInvocationHandler;
import com.example.proxy.service.impl.RealOrderServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.lang.reflect.Proxy;
@SpringBootTest
class ProxyApplicationTests {
@Test
void contextLoads() {
// 创建代理对象
OrderService proxy = (OrderService) Proxy.newProxyInstance(
// 接口
OrderService.class.getClassLoader(),
new Class[]{OrderService.class},
// 具体实现类
new OrderServiceInvocationHandler(new RealOrderServiceImpl()));
proxy.placeOrder();
}
}
import com.example.proxy.service.OrderService;
import com.example.proxy.service.impl.OrderServiceInvocationHandler;
import com.example.proxy.service.impl.RealOrderServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@SpringBootTest
class ProxyApplicationTests {
@Test
void contextLoads() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealOrderServiceImpl.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before placing order");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("After placing order");
return invoke;
}
});
OrderService proxy = (OrderService) enhancer.create();
proxy.placeOrder();
}
}
Spring AOP的底层就是基于上述两种代理方式实现的;
默认情况下,如果目标对象实现了相关接口,Spring会使用JDK动态代理;否则使用CGLIB。
<img alt="image-20240410162013253">
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
用于标注目标方法
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/* 日志描述 */
String value() default "";
}
@Aspect
@Component
@Slf4j
public class LogAspect {
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result, Log controllerLog){
log.info("方法返回值:{}", result);
log.info("注解描述:{}", controllerLog.value());
log.info("方法名:{}", joinPoint.getSignature().getName());
}
}
@Service
public class AopServiceImpl {
@Log("AOP test")
public String test(){
System.out.println("AOP test");
return "AOP success";
}
}
网上有种说法:在单元测试的类上加注解@EnableAspectJAutoProxy(true),但亲测无效。
Spring aop 是针对 Spring 的 bean 进行 AOP, 而 @Test 单元测试类不是Spring 的 Bean, 所以无法 aop.
故,需多封装一层
@Service
public class DataService {
@Autowired
private UserMapper userMapper;
// @MyDataSource("master")
@MyDataSource("slaver")
public void test()
{
userMapper.insertUser("aop", "aop");
System.out.println("动态数据源切换成功!");
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。