个人理解:

spring Aop 是什么:面向切面编程,类似于自定义拦截操作,支持拦截之前操作@Before,拦截之后操作@After,拦截环绕操作@Around。

什么情况下使用spring Aop:举例如下

  1. 当需要统计某些方法 or 指定xx开头的方法名 or 指定xx结尾的方法名 or 某些类下的方法 or 某些包下的方法 or 所有的方法的耗时统计或添加日志信息时,使用spring Aop 切面编程可以不用修改任何需要统计或添加日志的方法,只需很少一部分代码实现需要做的操作。
  2. 某交易系统需要限制每个登陆用户查询次数时,spring Aop 切面编程在不修改原有代码上可以完美实现。

code案例:

applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd "> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:propertiesConfig/test.properties</value>
</property>
</bean> <!-- 扫描@Controller注解 -->
<context:component-scan base-package="com.maven.project">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan> <!-- 开启AOP监听 只对当前配置文件有效 -->
<aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy> <task:executor id="executor" pool-size="5" />
<task:scheduler id="scheduler" pool-size="10" />
<task:annotation-driven executor="executor" scheduler="scheduler" /> <!-- 线程池 -->
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="10" />
<!-- 线程池维护线程所允许的空闲时间 -->
<property name ="keepAliveSeconds" value ="300" />
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="100" />
<!-- 线程池所使用的缓冲队列 -->
<property name="queueCapacity" value="25" />
</bean> <bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean> </beans>

  

maven pom.xml  spring Aop dependency

<!-- Spring AOP + AspectJ  -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<!-- end -->

  

spring Aop 切面业务处理类

package com.maven.project.web.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Component
@Aspect
public class CustomAspect { //com.maven.project.services包下(包括子包下 的)for开头的方法
@Pointcut("execution(* com.maven.project.services..for*(..))")
public void query(){} //所有使用@QuerySystem自定义注解的方法
@Pointcut("@annotation(com.maven.project.web.customAnnotations.QuerySystem)")
public void loginTimeOut(){} @Before("query()")//方法之前执行
public void queryBefore(JoinPoint joinPoint){
System.out.println("=======query start @Before ====方法名称:"+joinPoint.getSignature().getName());
} @After("query()")//方法之后执行
public void queryAfter(JoinPoint joinPoint){
System.out.println("=======query end @After ====方法名称:"+joinPoint.getSignature().getName());
} @Around("query()")//方法前后执行,如果需要返回值,则必须 return joinPoint.proceed(); 返回类型为Object
public void queryAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("=======query start @Around ====方法名称:"+joinPoint.getSignature().getName());
joinPoint.proceed();
System.out.println("=======query end @Around ====方法名称:"+joinPoint.getSignature().getName());
} @Around("loginTimeOut()")
public void times(ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("======= 登陆耗时:"+(end-start)/1000+" ====方法名称:"+joinPoint.getSignature().getName());
}
}

自定义注解

package com.maven.project.web.customAnnotations;
import java.lang.annotation.*; @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface QuerySystem {
String description() default "";
}

引用自定义注解的方法

    @RequestMapping("/login")
@QuerySystem //自定义注解引用
public void login(HttpServletRequest request, HttpServletResponse response) {
// 方法实现,,,,
}

execution 表达式
1、execution(): 表达式主体。
2、第一个*号:表示返回类型,*号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。 AspectJ的Execution表达式
execution()是最常用的切点函数,其语法如下所示: execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) 除了返回类型模式、方法名模式和参数模式外,其它项都是可选的。与其直接讲解该方法的使用规则,还不如通过一个个具体的例子进行理解。下面,我们给出各种使用execution()函数实例。 1)通过方法签名定义切点
execution(public * *(..))l
匹配所有目标类的public方法,但不匹配SmartSeller和protected void showGoods()方法。第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法; execution(* *To(..))l
匹配目标类所有以To为后缀的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一个*代表返回类型,而*To代表任意以To为后缀的方法; 2)通过类定义切点
execution(* com.baobaotao.Waiter.*(..))l
匹配Waiter接口的所有方法,它匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()方法。第一个*代表返回任意类型,com.baobaotao.Waiter.*代表Waiter接口中的所有方法; execution(* com.baobaotao.Waiter+.*(..))l
匹 配Waiter接口及其所有实现类的方法,它不但匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()这 两个Waiter接口定义的方法,同时还匹配NaiveWaiter#smile()和NaughtyWaiter#joke()这两个不在Waiter 接口中定义的方法。 3)通过类包定义切点
在类名模式串中,“.*”表示包下的所有类,而“..*”表示包、子孙包下的所有类。
execution(* com.baobaotao.*(..))l
匹配com.baobaotao包下所有类的所有方法; execution(* com.baobaotao..*(..))l
匹 配com.baobaotao包、子孙包下所有类的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及 com.baobaotao.dao.user包下的所有类的所有方法都匹配。“..”出现在类名中时,后面必须跟“*”,表示包、子孙包下的所有类; execution(* com..*.*Dao.find*(..))l
匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切点。 4)通过方法入参定义切点
切点表达式中方法入参部分比较复杂,可以使用“*”和“ ..”通配符,其中“*”表示任意类型的参数,而“..”表示任意类型参数且参数个数不限。 execution(* joke(String,int)))l
匹 配joke(String,int)方法,且joke()方法的第一个入参是String,第二个入参是int。它匹配 NaughtyWaiter#joke(String,int)方法。如果方法中的入参类型是java.lang包下的类,可以直接使用类名,否则必须使用全限定类名,如joke(java.util.List,int); execution(* joke(String,*)))l
匹 配目标类中的joke()方法,该方法第一个入参为String,第二个入参可以是任意类型,如joke(String s1,String s2)和joke(String s1,double d2)都匹配,但joke(String s1,double d2,String s3)则不匹配; execution(* joke(String,..)))l
匹配目标类中的joke()方法,该方法第 一个入参为String,后面可以有任意个入参且入参类型不限,如joke(String s1)、joke(String s1,String s2)和joke(String s1,double d2,String s3)都匹配。 execution(* joke(Object+)))l
匹 配目标类中的joke()方法,方法拥有一个入参,且入参是Object类型或该类的子类。它匹配joke(String s1)和joke(Client c)。如果我们定义的切点是execution(* joke(Object)),则只匹配joke(Object object)而不匹配joke(String cc)或joke(Client c)。

  

 

spring Aop 注解的更多相关文章

  1. Spring AOP注解为什么失效?90%Java程序员不知道

    使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方加,不然不会生效. 如下面几种场景 1.Controller直接调用Se ...

  2. Spring aop注解失效

    问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...

  3. spring aop注解方式与xml方式配置

    注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...

  4. spring aop注解配置

    spring aop是面向切面编程,使用了动态代理的技术,这样可以使业务逻辑的代码不掺入其他乱七八糟的代码 可以在切面上实现合法性校验.权限检验.日志记录... spring aop 用的多的有两种配 ...

  5. Spring AOP 注解和xml实现 --转载

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  6. Spring aop 注解参数说明

    在spring AOP中,需要使用AspectJ的切点表达式语言来定义切点. 关于Spring AOP的AspectJ切点,最重要的一点是Spring仅支持AspectJ切点指示器(pointcut ...

  7. 【学习笔记】Spring AOP注解使用总结

    Spring AOP基本概念 是一种动态编译期增强性AOP的实现 与IOC进行整合,不是全面的切面框架 与动态代理相辅相成 有两种实现:基于jdk动态代理.cglib Spring AOP与Aspec ...

  8. 6.spring:AOP(注解)

     spring Aop AOP面向切面编程,与OOP面向对象编程相辅相成 AOP中最基本的单元是切面 问题: 代码混乱:越来越多的业务需求(日志&验证)加入后,原有的业务方法急剧膨胀,每个方法 ...

  9. 转:Spring AOP 注解方式实现的一些“坑”

    使用过Spring AOP的注解方式实现,也入过不少坑,现在做一下记录,希望有同样需求的朋友可以少走弯路 使用之前还是先过一下官方文档吧,至少可以少走弯路,不用担心英文读不懂,其实只看代码例子就能理解 ...

随机推荐

  1. 代码-Weka的决策树类J48

    package kit.weka;   /** * desc:试试Weka的决策树类 * <code>J48Test</code> * */ import java.io.Fi ...

  2. Hive 0.12 Caused by: MetaException(message:Version information not found in metastore. )解决方法

    配置完成Mysql存储元数据信息,启动后测试show tables报错ERROR exec.DDLTask: org.apache.hadoop.hive.ql.metadata.HiveExcept ...

  3. HW4.44

    public class Solution { public static void main(String[] args) { double randX; double randY; int hit ...

  4. 新浪微博、腾讯微博、QQ空间、人人网、豆瓣 一键分享API

    新浪微博: http://service.weibo.com/share/share.php?url= count=表示是否显示当前页面被分享数量(1显示)(可选,允许为空) & url=将页 ...

  5. Win8关机 一直重启的问题 解决方案-摘自网络

    win8关机时自动重启的解决方法:关闭快递启动,默认是启动的,到控制面板 – 电源选项 – 选择电源按钮的功能 – 更改当前不可用的设置 – 关机设置 – 把勾去掉 关闭快速启动.这样就不会关机一直重 ...

  6. javascript 如何判断一个对象的类型

    <!DOCTYPE html> <html> <head> </head> <body> <script type="tex ...

  7. JS继承的几种方式

    JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一. 既然要实现继承,那么我们先定义一个父类: // 定义一个动物类 function Animal (name) { // 属性 this.n ...

  8. SQLite 入门教程(一)基本控制台(终端)命令 (转)

    转于: SQLite 入门教程(一)基本控制台(终端)命令 一.基本简介   SQLite 是一个自持的(self-contained).无服务器的.零配置的.事务型的关系型数据库引擎.因为他很小,所 ...

  9. iOS中事件的传递和响应者链条

    在iOS 开发中,常见的事件有三种类型,分别是: (1)触摸事件:平常手指在屏幕上滑动,产生的事件都是触摸事件 (2)加速计事件:微信的摇一摇就是典型的加速计事件 (3)远程控制事件:耳机控制歌曲上一 ...

  10. S2SH商用后台权限系统第一讲

    各位博友: 您好!从今天开始我们做一套商用的权限系统.功能包含用户管理.角色管理.模块管理.权限管理.大家知道每个商用系统肯定会拥有一套后台系统,我们所讲的权限系统是整个系统核心部分.本套系统技术有s ...