Spring AOP

什么是AOP

AOP是面对切面的额编程,通过以便以的方式和运行期动态代理实现程序供的统一维护的技术。

功能:日志记录,性能统计,安全控制,事务处理,异常处理等等。

AOP的实现方式

预编译:Aspectj

运行期动态代理:SpringAOP、JbossAOP。

AOP的基本概念

切面:一个关注点的模块化,这个关注点可能会横切多个对象

连接点:程序执行过程中的某个特定的点

通知:在切面的某个特定的连接点上执行的动作

切入点:匹配连接点的断言,在AOP中通知和一个切入点表达式关联

引入:在不修改类代码的前提下,为类添加新的方法和属性

目标对象:被一个或者多个切面所通知的对象

AOP代理:AOP框架创建的对象,用来实现切面契约

织入:把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象,分为:编译时的织入、类加载时织入、执行时织入

Advice通知:

前置通知,返回后通知,抛出异常后通知,退出时通知,环绕通知。

Spring中的AOP

用途:提供声明式的企业服务、允许用户定制自己的方面,以完成OOP和AOP的互补使用。

实现: 纯Java实现,目前只支持方法执行连接点 停供了一种AOP实现和Spring IOC容器之间的整合不会与Aspectj冲突。

Schema-based AOP

所有的切面和通知器都要放在<aop:config>中,可以包含pointcut,advisor,aspect元素。(必须按照顺序声明)

<aop:aspect>  id:指定切面的唯一标识符,rel:将该Bean作为一个切面。

<aop:pointcut>id:切入点的唯一标识符,execution:切入点的配置 

execution(public * *(..)) 切入点为所有的public方法执行时

execution(* set*(..))切入点为执行所有以set开头的方法时

execution(* xxx.yyy.zzz.aaa.*(..))切入点为执行aaa类中所有的方法时

execution(* xxx.yyy.zzz..(..))切入点为执行zzz包下所有方法时

execution(* xxx.yyy.zzz...(..))切入点为执行zzz包下及其子包的所有方法时

Advice:

before:<aop:before method="before" pointcut-ref="apppointcut"/>

前缀通知,在执行切入点前运行before方法。

after-returning:<aop:after-returning method="before" pointcut-ref="apppointcut"/>

返回之后通知,在切入点返回时运行before方法。

after-throwing:<aop:after-throwing method="before" pointcut-ref="apppointcut"/>

当切入点抛出异常时,运行before方法。

after: <aop:after method="before" pointcut-ref="apppointcut"/>

切入点结束之后,执行before方法

Around:方法的第一个参数必须是ProceedingJoinPoint类型,环绕通知

<aop:around method="before2" pointcut-ref="apppointcut"/>

public Object before2(ProceedingJoinPoint pjp){
    Object obj = null;
    try {
        System.out.println("before2 round1");
        obj = pjp.proceed();
        System.out.println("before2 round2");
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    return obj;
}

 

使用时一定要导入jar包,不然会报错

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appAspect' defined in Interface.AppConfig: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)#64cd705f' of type [org.springframework.aop.aspectj.AspectJMethodBeforeAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#64cd705f': Failed to introspect bean class [org.springframework.aop.aspectj.AspectJMethodBeforeAdvice] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/JoinPoint

在Maven中添加依赖

  <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>

aop 标签顺序使用错误

org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 11 in XML document from class path resource [spring-config.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 68; cvc-complex-type.2.4.a: 发现了以元素 'aop:before' 开头的无效内容。应以 '{"http://www.springframework.org/schema/aop":pointcut, "http://www.springframework.org/schema/aop":advisor, "http://www.springframework.org/schema/aop":aspect}' 之一开头。

	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:399)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:252)
	at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
	at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:614)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:515)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at Interface.test1.test4(test1.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 68; cvc-complex-type.2.4.a: 发现了以元素 'aop:before' 开头的无效内容。应以 '{"http://www.springframework.org/schema/aop":pointcut, "http://www.springframework.org/schema/aop":advisor, "http://www.springframework.org/schema/aop":aspect}' 之一开头。
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:284)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:453)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3231)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1791)
	at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:741)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
	at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:76)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:429)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
	... 36 more

使用aop时,pointcut可以在aspect外,但是before、after-returning、after-throwing、after、around必须在aspect内部。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值