- 浏览: 55697 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
p_3er:
blucedong 写道你好我在做struts1.3+spri ...
基于annotation的struts1.3+hibernate3.3+spring2.5 -
blucedong:
你好我在做struts1.3+spring3.0+hibern ...
基于annotation的struts1.3+hibernate3.3+spring2.5
第三章 AOP 基于@AspectJ的AOP
在前面,我们分别使用Pointcut、Advice、Advisor接口来描述切点、增强、切面。而现在我们使用@AdpectJ注解来描述。
在下面的例子中,我们是使用Spring自动扫描和管理Bean。
(http://blog.csdn.net/p_3er/article/details/9239605)
3.6.1一个简单的例子
@Repository public class UserDaoImpl implements UserDao { public void save() { System.out.println("保存用户..."); } public void delete() { System.out.println("删除用户..."); } }
b、通过一个POJO使用@AspectJ管理切面
/* * 通过@Aspect把这个类标识管理一些切面 */ @Aspect @Component public class FirstAspect { /* * 定义切点及增强类型 */ @Before("execution(* save(..))") public void before(){ System.out.println("我是前置增强..."); } }
c、配置
配置的时候要引入aop命名空间及打开@AspectJ切面驱动器
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <!— 驱动器自动为Spring容器中那些匹配@AspectJ切面的Bean创建代理,完成切面积入 --> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserDao userDao = (UserDao) context.getBean("userDaoImpl"); userDao.save(); userDao.delete();
e、结果
我是前置增强... 保存用户... 删除用户...
3.6.2增强类型及其使用
@Before前置增强
@Before(value= "切入点表达式或命名切入点",argNames = "指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔")
3.6.1中的增强使用:@Before(value="execution(*save(..))")是缺省了value,直接键入值。
a、目标类
@Service public class UserService { public void say(String name){ System.out.println("service say:"+name); } public void run(String way){ System.out.println("service run:"+way); } }
b、通过一个POJO使用@AspectJ管理切面
@Aspect @Component public class BeforAspectj { /* *单独配置切点。给切点命名。 */ @Pointcut(value="execution(* say(..)) && args(param)",argNames="param") public void beforePointcut(String param){ } @Before(value="beforePointcut(s)",argNames="s") public void beforeAdvice(String s){ System.out.println("beforeAdvice:"+s); } }
@Aspect @Component public class BeforAspectj { @Before(value="execution(* say(..)) && args(s)",argNames="s") public void beforeAdvice(String s){ System.out.println("beforeAdvice:"+s); } }
c、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService"); service.say("zhangsan"); service.run("street");
e、结果
beforeAdvice:zhangsan service say:zhangsan service run:street
@AfterReturning后置增强
@AfterReturning(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
returning="目标对象的返回值")
pointcut与value是一样的。如果使用pointcut来声明,那么前面声明的value就没用了。
@Service public class UserService { public void say(String name){ System.out.println("service say:"+name); } public void run(String way){ System.out.println("service run:"+way); } public String getName(String name){ System.out.println("service getName:"+name); return "MR"+name; } }
b、通过一个POJO使用@AspectJ管理切面
@Aspect @Component public class AfterReturningAspectj { /* * 即获取返回值,又获取传入的参数 */ @AfterReturning( value="execution(* cn.framelife.spring..*.getName(..)) && args(sname)", returning="name", argNames="name,sname") public void afterGetNameAdvice(Object object,String sname){ System.out.println("afterGetNameAdvice:"+ (String)object+"--"+sname); } /* * 只要增强,返回值和参数都不理会 */ @AfterReturning(value="execution(* cn.framelife.spring..*.run(..))") public void afterRunAdvice(){ System.out.println("afterRunAdvice"); } }
c、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService "); service.getName("zhangsan"); service.run("street");
e、结果
servicegetName:zhangsan afterGetNameAdvice:MRzhangsan--zhangsan servicerun:steet afterRunAdvice
@AfterThrowing异常抛出增强、@After Final增强
@AfterThrowing(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
throwing="异常对应参数名")
@After( value="切入点表达式或命名切入点",argNames="参数列表参数名")
@After不管是抛出异常或者是正常退出,该增强都会执行。相当于try-catch-final里的final代码块。
a、目标类
@Service public class UserService { public void tryThrow(){ System.out.println("service tryThrow"); throw new RuntimeException("i am a runtime exception"); } }
b、通过一个POJO使用@AspectJ管理切面
@Aspect @Component public class ThrowAspectj { @AfterThrowing(value="execution(* cn.framelife.spring..tryThrow(..))", throwing="exception", argNames="exception") public void afterThrowAdvisor(Exception exception){ System.out.println("afterThrowAdvisor:"+exception.getMessage()); } @After(value="execution(* cn.framelife.spring..tryThrow(..))") public void finalThrowAdvisor(){ System.out.println("finalThrowAdvisor"); } }
c、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService "); service.tryThrow();
e、结果
servicetryThrow afterThrowAdvisor:iam a runtime exception finalThrowAdvisor Exceptionin thread "main" java.lang.RuntimeException:i am a runtime exception
@Around环绕增强
@Around( value="切入点表达式或命名切入点",argNames="参数列表参数名")
a、目标类
@Service public class UserService { public void round(){ System.out.println("service round"); } public void run(String way){ System.out.println("service run:"+way); } public String getName(String name){ System.out.println("service getName:"+name); return "MR"+name; } }
b、通过一个POJO使用@AspectJ管理切面
@Aspect @Component public class AroundAspect { @Around(value="execution(* cn.framelife.spring..round(..))") public Object aroundAdvisor(ProceedingJoinPoint point) throws Throwable{ System.out.println("before method"); Object target = point.proceed(); System.out.println("after method"); return target; } }
c、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService"); service.round(); service.run("street");
e、结果
beforemethod serviceround aftermethod servicerun:street afterRunAdvice
@DeclareParents引介增强
@DeclareParents(
value="AspectJ语法类型表达式",
defaultImpl=引入接口的默认实现类)
下面的例子是Waiter为目标类,然后让目标类拥有ISeller接口的功能:
目标类与其接口:
public interface IWaiter { public void service(); }
@Component public class Waiter implements IWaiter { @Override public void service() { System.out.println("service"); } }
运行期织入到目标类的功能类与其接口:
public interface ISeller { public void sell(); }
public class Seller implements ISeller { @Override public void sell() { System.out.println("sell"); } }
@Aspect @Component public class DeclareAspect { /* * value里面配置目标类 * defaultImpl是功能类的实现类 */ @DeclareParents( value="cn.framelife.spring.aspectj.Waiter", defaultImpl=Seller.class) private ISeller seller; //使用功能类接口声明一个对象 }
c、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); IWaiter waiter = (IWaiter) context.getBean("waiter"); waiter.service(); ISeller seller = (ISeller)waiter; seller.sell();
e、结果
service sell
3.6.3切点函数
带@开头的函数都是针对注解类的。而不带@的函数是针对普通类的。
execution()
execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
除了返回类型模式、方法名模式和参数模式外,其它都是可选的。
1)通过方法签名定义切点
execution(public* *(..))
匹配所有目标类的public方法,但不匹配SmartSeller和protectedvoid showGoods()方法。第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法;
execution(* *To(..))
匹配目标类所有以To为后缀的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一个*代表返回类型,而*To代表任意以To为后缀的方法;
2)通过类定义切点
execution(*com.baobaotao.Waiter.*(..))
匹配Waiter接口的所有方法,它匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()方法。第一个*代表返回任意类型,com.baobaotao.Waiter.*代表Waiter接口中的所有方法;
execution(*com.baobaotao.Waiter+.*(..))
匹配Waiter接口及其所有实现类的方法,它不但匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()这两个Waiter接口定义的方法,同时还匹配NaiveWaiter#smile()和NaughtyWaiter#joke()这两个不在Waiter接口中定义的方法。
3)通过类包定义切点
在类名模式串中,“.*”表示包下的所有类,而“..*”表示包、子孙包下的所有类。
execution(*com.baobaotao.*(..))
匹配com.baobaotao包下所有类的所有方法;
execution(*com.baobaotao..*(..))
匹配com.baobaotao包、子孙包下所有类的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及com.baobaotao.dao.user包下的所有类的所有方法都匹配。“..”出现在类名中时,后面必须跟“*”,表示包、子孙包下的所有类;
execution(*com..*.*Dao.find*(..))
匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切点。
4)通过方法入参定义切点
切点表达式中方法入参部分比较复杂,可以使用“*”和“..”通配符,其中“*”表示任意类型的参数,而“..”表示任意类型参数且参数个数不限。
execution(*joke(String,int)))
匹配joke(String,int)方法,且joke()方法的第一个入参是String,第二个入参是int。它匹配NaughtyWaiter#joke(String,int)方法。如果方法中的入参类型是java.lang包下的类,可以直接使用类名,否则必须使用全限定类名,如joke(java.util.List,int);
execution(*joke(String,*)))
匹配目标类中的joke()方法,该方法第一个入参为String,第二个入参可以是任意类型,如joke(Strings1,String s2)和joke(Strings1,double d2)都匹配,但joke(Strings1,double d2,String s3)则不匹配;
execution(*joke(String,..)))
匹配目标类中的joke()方法,该方法第一个入参为String,后面可以有任意个入参且入参类型不限,如joke(Strings1)、joke(Strings1,String s2)和joke(Strings1,double d2,String s3)都匹配。
execution(*joke(Object+)))
匹配目标类中的joke()方法,方法拥有一个入参,且入参是Object类型或该类的子类。它匹配joke(Strings1)和joke(Clientc)。如果我们定义的切点是execution(*joke(Object)),则只匹配joke(Objectobject)而不匹配joke(Stringcc)或joke(Clientc)。
args()
该函数的入参是一个类名,表示目标类的方法入参对象是指定的类(包含子类),切点匹配。它允许类后后使用+通配符后缀,但添加也不添加+效果是一样的。
例子:
public class User implements Serializable { }
b、目标类
@Service public class UserService { public void say(User user){ System.out.println("say"); } }
c、通过一个POJO使用@AspectJ管理切面
@Aspect @Component public class BeforAspectj { @Before(value="args(cn.framelife.spring.aspectj.User)") public void beforeAdvice(){ System.out.println("beforeAdvice"); } }
d、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
e、测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService"); service.say(new User());
f、结果
beforeAdvice say
within()
通过类的匹配模式串声明切点。该函数定义的连接点是针对目标类(不能是接口)而言,而不是针对运行时的对象,这与execution()函数相同。Execution()所指定的连接点可以是小到参数,而within()指定的连接点最小只能是类。
within(cn.framelife.spring.aspectj.UserService)
匹配UserService类下所有的方法。
within(cn.framelife.spring.aspectj.*)
匹配cn.framelife.spring.aspectj包下所的的类,但不包括子孙包。cn.framelife.spring.aspectj.abc.AbcService是不匹配的。
within(cn.framelife.spring.aspectj..*)
匹配cn.framelife.spring.aspectj包及其子孙包下所的的类。
target()与this()
target()函数是通过判断目标类是否按类型匹配指定类决定连接点是否匹配。
target(cn.framelife.spring.aspectj.UserService)
匹配这UserService类及其子孙类的所有方法。如果UserService是一个接口,那么会匹配UserService的实现类及实现类的子孙类中的所有的方法。
this()函数是通过判断代理类是否按类型匹配指定类决定连接点是否匹配。
一般情况下,使用this()和target()定义切点,两者是等效的:
target(cn.framelife.spring.aspectj.UserService)与this(cn.framelife.spring.aspectj.UserService)是一样的。无论UserService是一个类还是一个接口。
两者区别体现在通过引介切面产生代理对象时。
@annotation()
表示标注了某个自定义注解的方法,使用切面。
@Retention(value=RetentionPolicy.RUNTIME) @Target(value=ElementType.METHOD) public @interface BeforeAdvisor { boolean value() default false; }
@Aspect @Component public class BeforAspectj { @Before(value="@annotation(cn.framelife.spring.aspectj.annotation.BeforeAdvisor)") public void beforeAdvice(){ System.out.println("beforeAdvice"); } }
c、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
d、目标类
@Service public class UserService { @BeforeAdvisor public void annotation(){ System.out.println("annotation"); } }
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService"); service.annotation();
f、结果
beforeAdvice annotation
@args()
该函数的入参是一个注解类的类名,表示运行时目标类方法的入参对象的类标注了指定的注解。
@Retention(value=RetentionPolicy.RUNTIME) @Target(value=ElementType.TYPE) public @interface UserAnnotation { }
b、切面管理
@Aspect @Component public class BeforAspectj { @Before(value="@args(cn.framelife.spring.aspectj.annotation.UserAnnotation)") public void beforeAdvice(){ System.out.println("beforeAdvice"); } }
c、实体类(使用上面定义的注解)
@UserAnnotation public class User implements Serializable { }
d、目标类
@Service public class UserService { public void annotation(){ System.out.println("annotation"); } public void say(User user){ System.out.println("say"); } }
e、配置和3.6.1中一样
<?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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <aop:aspectj-autoproxy/>
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); UserService service = (UserService) context.getBean("userService"); service.say(new User());
g、结果
beforeAdvice say
@within和@target()
@winthin(A)匹配任意标注了@A的目标类。@target(A)匹配@A的类及子孙类。
@annotation是标注在目标类的方法
@args是标注目标类方法的入参对象的类
@winthin与@target是标注目标类
注意
上面的函数(特别是args())除了可以指定类名外,还可以指定参数名,将目标对象连接点上的方法入参绑定到增强的方法中。如:@Before中的例子。
3.6.4通配符与逻辑运算符
@Aspectj支持3种通配符:
*匹配任意字符,但它只能匹配上下文中的一个元素
..匹配任意字符,可以匹配上下文中的多个元素,但在表示类时,必须和*联合使用,而在表示入参时则单独使用。
+表示按类型匹配指定类及其子孙类,必须跟在类名后面。如cn.framelife.spring.UserService+表示UserService类及其子类。
函数支持:
支持所有的通配符的函数:execution()、within()
仅支持+通配符的函数:args()、this()、targ()。虽然这三个函数可以支持+通配符,但对于这些函数来说使用和不使用+都是一样的。
不支持通配符的函数:@args、@within、@target()、@annotation()。也就是所有用于注解上的函数都不支持通配符。
@Aspectj支持的逻辑运算符:
&&与
||或
!非
相关推荐
@AspectJ是Spring AOP的一种注解驱动方式,它极大地简化了AOP的使用。本篇文章将深入探讨@AspectJ的使用方法和背后的原理。 首先,我们需要理解面向切面编程(AOP)的基本概念。AOP是一种编程范式,它允许开发者将...
本实例将带你深入理解并实践Spring AOP与@AspectJ的结合使用。 首先,了解AOP的基本概念。面向切面编程是一种编程范式,它允许程序员定义“切面”,即跨越多个对象的行为或责任。这些切面可以包含业务逻辑、日志、...
`基于@AspectJ配置Spring AOP之一 - 飞扬部落编程仓库-专注编程,网站,专业技术.htm`和其关联的`_files`目录可能包含了一个详细的教程或演示如何配置和运行@AspectJ的Spring AOP应用程序。 通过以上内容,我们可以...
Spring AOP的实现基于动态代理,对于接口实现类,它使用Java的`java.lang.reflect.Proxy`类来创建代理对象;对于没有接口的类,Spring使用CGLIB库生成子类。在运行时,Spring AOP会根据切面定义生成代理对象,然后...
一个基于@AspectJ的spring2.0 AOP应用实例,很小很简单,没有任何额外信息,最适合AOP入门学习。使用log4j打印信息。把项目直接import进myeclipse就可以使用啦......
@AspectJ是一种基于Java语言的AOP实现,允许在切面类上直接使用注解定义切点和通知。这种方式更加简洁和直观。例如: ```java @Aspect @Component public class LoggingAspect { @Before("execution(* ...
这里,`<aop:aspectj-autoproxy>`元素启用了基于注解的AOP代理,`<bean>`标签注册了我们的`LoggingAspect`类。 最后,当Spring启动时,它会自动检测到`LoggingAspect`类,并在合适的时候调用其定义的通知。现在,...
Spring 提供了两种主要的 AOP 实现方式:基于代理的和基于 AspectJ 的。基于代理的方式是 Spring 默认的实现,它通过 JdkDynamicProxy 或 CGLIB 创建代理对象来实现切面。而基于 AspectJ 的方式则更为强大,它允许...
切入点表达式是基于 AspectJ 的语言,用于指定通知应该在哪些方法执行。例如,`@Before("execution(* com.example.service.*.*(..))")`表示在`com.example.service`包下的所有类的所有方法执行前触发前置通知。 5. ...
本篇内容将对Spring AOP中基于AspectJ注解的使用进行总结,并通过实际案例进行解析。 首先,让我们理解AspectJ注解在Spring AOP中的核心概念: 1. **@Aspect**: 这个注解用于定义一个类为切面,这个类将包含切点和...
AspectJ是一个成熟的AOP框架,Spring在其AOP实现中整合了AspectJ,提供了更强大的面向切面编程能力。本篇文章将详细探讨在Spring 2.5中使用AspectJ进行AOP开发所需的知识点。 首先,我们需要理解AOP的核心概念: 1....
**AOP编程之AspectJ实战** 在软件开发中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,旨在减少代码的重复性和提高模块化程度。AOP通过将关注点(如日志记录、事务管理、安全性检查等)...
AspectJ 是一种基于 Java 语言的 AOP 实现,它可以在编译时织入Aspect,从而解决@Autowired 依赖注入失败的问题。 四、结论 Spring AOP 导致@Autowired 依赖注入失败的解决方法有两种:将方法修饰符改为 public 和...
本教程将探讨如何在Spring中结合AspectJ实现AOP,包括基于XML配置和基于注解的方式。 **一、AOP基本概念** AOP的核心概念有切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)和引入...
总结来说,基于@AspectJ的AOP使得在Web开发中可以方便地实现横切关注点,将业务逻辑与辅助功能(如日志、事务处理)分离,提高了代码的模块化程度和可维护性。通过注解和XML配置,我们可以轻松地定义和应用切面,...
3.AOP 中使用自定义注解 3.0 创建一个SpringBoot项目 3.1 引入 POM 依赖 3.1.1 引入springboot aop依赖 3.1.2 引入fastjson依赖 3.2 .编写配置类SpringConfig.java 3.3 添加一个自定义注解 @MyAop 3.4 将此注解添加...