标签:href val rgs 函数 pojo inter not parent 入参
Spring在新版本中对AOP功能进行了重要的增强:
@param @return 等Javadoc标签就是注解标签,为第三方工具提供了描述程序代码的注释信息。Java5.0注解可以看做javadoc和Xdoclet标签的延伸与发展。在Java5.0中可以自定义这些标签,并通过java语言的反射机制来获取类中标注的注解,完成特定的功能。
注解是代码的副属信息,遵循一个原则:注解语言不能直接干涉程序代码的运行,无论删除或增加注解,代码都能正常运行。第三方工具可以利用代码中的注解间接控制程序代码的运行,他们通过java反射机制读取注解的信息,并根据这些信息更改目标程序的逻辑,SpringAOP对@AspectJ提供支持,正是采取这种方法。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//通过该注解定义一个切面
@Aspect
public class PreGreetingAspect {
@Before("execution(* greetTo(..))")//定义切点和增强类型
public void beforeGreeting(){//增强的横切逻辑
System.out.println("How are you");
}
}
测试类
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
public class AspectJProxyTest {
public static void main(String[] args) {
Waiter target = new NaiveWaiter();
//定义一个Aspect类型的代理工厂
AspectJProxyFactory factory = new AspectJProxyFactory();
//设置代理目标类
factory.setTarget(target);
//添加切面类
factory.addAspect(PreGreetingAspect.class);
//生成织入切面的代理对象
Waiter proxy = factory.getProxy();
proxy.greetTo("欢欢");
proxy.serveTo("欢欢");
}
}
此时会发现,在PreGreetingAspect 切面类中定义的前置方法和通过BeforeAdvice接口定义的前置方法增强不一样,一个明显的区别是PreGreetingAspect 类的beforeGreeting()方法没有任何入参,而BeforeAdvice的接口方法before(Method method, Object[] args, Object target)的入参提供了一条访问目标对象方法和入参的途径。@Aspect定义的切面也提供了访问目标对象连接点信息的方法。
xml配置
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--目标bean-->
<bean id="waiter" class="com.ijianghu.advice.impl.NaiveWaiter"/>
<!--使用定义了@AspectJ的切面-->
<bean class="com.ijianghu.aspect.PreGreetingAspect"/>
<!--自动代理创建器,自动将@AspectJ注解切面类织入目标bean中-->
<!--AnnotationAwareAspectJAutoProxyCreator能够将AspectJ注解切面类自动织入到目标Bean中。-->
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
/>
</beans>
schema-aop配置
<?xml version="1.0" encoding="UTF-8"?>
<!--首先引入aop命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop">
<!--aspectj-autoproxy自动为Spring容器中那些匹配@aspectj切面的Bean创建代理,完成切面织入-->
<!--Spring在内部依旧使用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,
具体实现细节被aop:aspectj-autoproxy 隐藏起来-->
<aop:aspectj-autoproxy/>
<bean id="waiter" class="com.ijianghu.advice.impl.NaiveWaiter"/>
<bean class="com.ijianghu.aspect.PreGreetingAspect"/>
</beans>
切点表达式由关键字和操作参数组成,如execution(* greetTo(..))
Spring支持9个@AspectJ切点表达式函数,用不同的方式描述目标类的连接点,根据描述对象的不同,大致分为4类:
@Aspect支持3种通配符
:匹配任意字符,但它只能匹配上下文中的一个元素
..:匹配任意字符,可以匹配上下文中的多个元素,但在表示类时,必须和联合使用,而在入参时则单独使用。
+:表示按类型匹配指定类的所有类,必须跟在类名后面,如com.smart.Car+。继承或扩展指定类的所有类,同时还包括指定类本身。
[详情参考博客](https://blog.csdn.net/gexiaoyizhimei/article/details/99988144)
切点表达式由切点函数组成,切点函数之间还可以进行逻辑运算,组成复合切点。Spring支持以下切点运算符
Spring本身使用接口描述各种增强类型,@AspectJ也为各种增强类型提供了不同的注解类,它们位于org.aspectj.lang.annotation.*包中。这些注解拥有若干个成员,可以通过成员完成定义切点信息,绑定连接参数等操作。注解期限都是RetentionPolicy.RUNTIME,标注目标都是ElementType.METHOD。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
@Aspect
public class EnableSellerAspect {
@DeclareParents(value = "com.ijianghu.advice.impl.NaiveWaiter",//指定要增强的目标类
defaultImpl = com.ijianghu.aspect.impl.SmartSeller.class) //指定目标增强实现类
public Seller seller; //要实现的目标接口
}
<?xml version="1.0" encoding="UTF-8"?>
<!--首先引入aop命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop">
<!--aspectj-autoproxy自动为Spring容器中那些匹配@aspectj切面的Bean创建代理,完成切面织入-->
<!--Spring在内部依旧使用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,
具体实现细节被aop:aspectj-autoproxy 隐藏起来-->
<aop:aspectj-autoproxy/>
<bean id="waiter" class="com.ijianghu.advice.impl.NaiveWaiter"/>
<bean class="com.ijianghu.aspect.declare.EnableSellerAspect"/>
</beans>
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DeclareAspectJProxyTest {
public static void main(String[] args) {
String configPath = "com\\ijianghu\\aspect\\config\\applicationContext-schema-declare.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter) ctx.getBean("waiter");
waiter.greetTo("欢欢");
Seller seller = (Seller)waiter;
seller.sell("beer");
}
}
切点函数是AspectJ表达式语言的核心,也是使用@AspectJ进行切面定义的难点。
标签:href val rgs 函数 pojo inter not parent 入参
原文地址:https://www.cnblogs.com/nangonghui/p/13170383.html