AOP4
AOP5
execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?)
AOP6
@Component
@Aspect
public class MyAspect {
@Pointcut(value = "execution(* AOP6.*.*(..))")
public void setall(){}
@Before("setall()")
public void before(JoinPoint jp){
System.out.println("--------before-------");
}
@After("setall()")
public void after(JoinPoint jp){
System.out.println("---------after------");
}
@Around("setall()")
public Object around(ProceedingJoinPoint pjp){
System.out.println("--------around---------");
try {
Object obj=pjp.proceed();
System.out.println("-----around-----"+ obj);
return obj;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
@AfterThrowing(value = "setall()",throwing = "e")
public void throwing(JoinPoint jp,Throwable e){
System.out.println("--------throwing-------"+e.getMessage());
}
@AfterReturning(value = "setall()",returning = "obj")
public void returning(JoinPoint jp,Object obj){
System.out.println("-------returning-------"+obj);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="AOP6"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
AOP7
@Component
@Aspect
public class MyAspect {
public void before(){
System.out.println("------before-------");
}
public void after(){
System.out.println("------after--------");
}
}
public class BeanPostProcessor implements org.springframework.beans.factory.config.BeanPostProcessor{
@Nullable
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("---before----"+bean);
return bean;
}
@Nullable
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("-------after----");
return Proxy.newProxyInstance(BeanPostProcessor.class.getClassLoader(),bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MyAspect ma=new MyAspect();
ma.before();
Object obj=method.invoke(bean,args);
ma.after();
return obj;
}
});
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="AOP7"></context:component-scan>
<bean class="AOP7.BeanPostProcessor"></bean>
</beans>
jdk动态代理
特点
Interface:对于JDK Proxy,业务类是需要一个Interface的,这是一个缺陷;
Proxy:Proxy类是动态产生的,这个类在调用Proxy.newProxyInstance()方法之后,产生一个Proxy类的实力。实际上,这个Proxy类也是存在的,不仅仅是类的实例,这个Proxy类可以保存在硬盘上;
Method:对于业务委托类的每个方法,现在Proxy类里面都不用静态显示出来。
InvocationHandler:这个类在业务委托类执行时,会先调用invoke方法。invoke方法在执行想要的代理操作,可以实现对业务方法的再包装。
总结:
JDK动态代理类实现了InvocationHandler接口,重写的invoke方法。
JDK动态代理的基础是反射机制(method.invoke(对象,参数))Proxy.newProxyInstance()
cglib动态代理
特点
原理是对指定的目标生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
注意:jdk的动态代理只可以为接口去完成操作,而cglib它可以为没有实现接口的类去做代理,也可以为实现接口的类去做代理。
代理模式
给某一个对象(目标对象)提供一个代理,并由代理对象控制原对象(目标对象)的引用进行操作,这种模式一般称之为代理模式。
代理模式可以在不改变原程序代码的前提下,对功能进行扩充。通过代理模式,我们可以很方便的给代码添加日志记录,事务控制,权限控制等一系列功能。Spring AOP(面向切面编程)就用到了动态代理模式。