AOP:是一种面向切面的编程范式,是一种编程思想,旨在通过分离横切关注点,提高模块化,可以跨越对象关注点。Aop的典型应用即spring的事务机制,日志记录。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。主要功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等;主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

  AspectJ和Spring AOP 是AOP的两种实现方案,Aspectj是aop的java实现方案,是一种编译期的用注解形式实现的AOP;Spring aop是aop实现方案的一种,它支持在运行期基于动态代理的方式将aspect织入目标代码中来实现aop,其中动态代理有两种方式(jdk动态代理和cglib动态代理),这里不展开说。这里有几个概念,需要正确理解:

  joinPoint:连接点。在spring中只支持方法连接点,连接点指的是可以使用advice(增强)的地方,例如一个类中有5个方法,那么这5个方法,那么这5个方法都可以是连接点。

  pointcut:切点。可理解为实实在在的连接点,即切入advice(增强)的点。例如一个类中有5个方法,其中有3个方法(连接点)需要织入advice(增强),那么这3个需要织入advice的连接点就是切点。

  advice:增强。实际中想要添加的功能,如日志、权限校验。

  advisor:切面。由切点和增强相结合而成,定义增强应用到哪些切点上。

  Spring支持AspectJ的注解式切面编程。使用方式如下:

  (1)使用@Aspect声明是一个切面

  (2)使用@After、@Before、@Around定义增强(advice),可以直接将拦截规则作为参数(pointcut),其中@Around可以控制目标方法是否执行,并且改变返回结果。

  (3)为了使切点复用,可以使用@PointCut专门定义拦截规则,拦截规则方式有两种:基于注解拦截和基于方法规则拦截,其中注解式拦截能够很好的控制拦截粒度和获取丰富的信息,Spring本身在处理事务和数据缓存也是使用此种方式的拦截。

  spring-aop使用demo如下:

  1、pom.xml,加入以下依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>

  2、自定义一个注解,作为拦截规则

  

package powerx.io;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Mylog { String level() default "info";
}

  3、编写功能类

  

package powerx.io;

import org.springframework.stereotype.Service;

@Service
public class UserService { @Mylog(level="debug")
public void add() {
System.out.println("添加用户");
} @Mylog
public void find() {
System.out.println("查看用户");
}
}
package powerx.io;

import org.springframework.stereotype.Service;

@Service
public class StudentService { public void add() {
System.out.println("添加student");
} @Mylog(level="debug")
public Object update(String name) {
System.out.println("更新student");
return "更新成功";
}
}

  4、切面

package powerx.io;

import java.lang.reflect.Method;

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.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogAspect { @Pointcut("@annotation(powerx.io.Mylog)")
public void annotationPointCut() {}; @After("annotationPointCut()")
public void after(JoinPoint joinPoint) {
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
Mylog mylog = method.getAnnotation(Mylog.class);
System.out.println("日志等级"+ mylog.level()+ "注解式拦截");
} @Before("execution(* powerx.io.StudentService.*(..))")
public void before(JoinPoint joinPoint) {
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
System.out.println("方法规则拦截" + method.getName());
} @Around("@annotation(powerx.io.Mylog)&&execution(* powerx.io.StudentService.*(..))")
public Object around(ProceedingJoinPoint joinPoint) {
Object result = null;
Object[] obs = joinPoint.getArgs();
if(obs != null && obs.length >0) {
String name = (String) obs[0];
if("zhangsan".equals(name)) {
try {
result = joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
}else {
result = "只有张三才允许修改";
}
}
return result;
}
}

  5、java配置

package powerx.io;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@ComponentScan("powerx.io")
@EnableAspectJAutoProxy//启动Spring对AspectJ的支持
public class JavaConfig { }

  6、主类

package powerx.io;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
UserService us = ac.getBean(UserService.class);
us.add();
us.find();
System.out.println("------------------------");
StudentService ss = ac.getBean(StudentService.class);
ss.add();
Object ob = ss.update("zhangsan");
System.out.println(ob);
System.out.println("------------------------");
Object ob2 = ss.update("lisi");
System.out.println(ob2);
ac.close();
}
}

  运行主类,控制台显示如下:

spring项目中aop的使用的更多相关文章

  1. spring boot 中AOP的使用

    一.AOP统一处理请求日志 也谈AOP 1.AOP是一种编程范式 2.与语言无关,是一种程序设计思想 面向切面(AOP)Aspect Oriented Programming 面向对象(OOP)Obj ...

  2. spring 项目中在类中注入静态字段

    有时spring 项目中需要将配置文件的属性注入到类的静态字段中 例如:文件上传 //文件上传指定上传位置 //resource-dev.properties 有如下参数 #upload UPLOAD ...

  3. java web项目(spring项目)中集成webservice ,实现对外开放接口

    什么是WebService?webService小示例 点此了解 下面进入正题: Javaweb项目(spring项目)中集成webservice ,实现对外开放接口步骤: 准备: 采用与spring ...

  4. spring项目中使用定时任务

    当我们希望在某个时间点来执行一些业务方法的时候就用到定时任务,在spring的项目中使用定时任务很简单.如下 第一步.加入jar包 <dependency> <groupId> ...

  5. spring项目中如何添加定时器以及在定时器中自动生成sprng注入对象

    最近做了一个java的项目,部门领导给了一套代码让我尽快掌握,说心里话本人真心不喜欢java的这种项目方式,各种配置各种xml文件简直头都大了,下面就将我遇到的其中一个我认为是坑的地方整理出来,希望能 ...

  6. 9. spring项目中web.xml详解解读

    引言:本篇博客的内容大部分都来自网上,有的是直接copy,有的是自己整理而来.既然网上已经有了,为啥还有自己copy呢? 感觉是因为网上的东西太散了或者是样式不够美观,所以自己又copy了一遍.如有侵 ...

  7. Spring项目中执行Java脚本

    问题:在已搭建好Spring环境的JavaWeb项目中,怎么运行一段Java代码,执行一些类似脚本的功能. 情况一:测试局部功能,不需要依赖Spring框架的. 方法:IDEA中新建一个类,编写主函数 ...

  8. Spring项目中Properties不能加载多个的问题

    A模块和B模块都分别拥有自己的Spring XML配置,并分别拥有自己的配置文件: A模块 A模块的Spring配置文件如下: <?xml version="1.0" enc ...

  9. spring项目中 通过自定义applicationContext工具类获取到applicationContext上下文对象

    spring项目在服务器启动的时候 spring容器中就已经被创建好了各种对象,在我们需要使用的时候可以进行调用. 工具类代码如下 import org.springframework.beans.B ...

随机推荐

  1. 编写高质量代码改善C#程序的157个建议——建议105:使用私有构造函数强化单例

    建议105:使用私有构造函数强化单例 单例指一个类型只生成一个实例对象.单例的一个简单实现如下所示: static void Main(string[] args) { Singleton.Insta ...

  2. Elasticsearch 5.6.5 安装head插件

    head安装包,下载地址:https://github.com/mobz/elasticsearch-head/archive/master.zip head 插件不能放在elasticsearch- ...

  3. android之实现底部TabHost

    先说布局文件,如下:利用android:layout_alignParentBottom="true" 实现底部显示 <?xml version="1.0" ...

  4. 使用PowerShell自动部署ASP.NetCore程序到IIS

    Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能.有关于更多PowerShell的信息,可参阅百度词条 接 ...

  5. C# Winform Label内容根据其宽度自动调整字体大小

    C# Winform Label内容根据其宽度自动调整字体大小 项目,有个要求,Label中显示的内容,能够根据其宽度自动调整字体的大小进行显示,刚刚开始的时候,总是想着通过不同的方法来直接测量内容的 ...

  6. ASP.NET Core中使用自定义验证属性控制访问权限

    在应用中,有时我们需要对访问的客户端进行有效性验证,只有提供有效凭证(AccessToken)的终端应用能访问我们的受控站点(如WebAPI站点),此时我们可以通过验证属性的方法来解决. 一.publ ...

  7. 利用Crawlspider爬取腾讯招聘数据(全站,深度)

    需求: 使用crawlSpider(全站)进行数据爬取 - 首页: 岗位名称,岗位类别 - 详情页:岗位职责 - 持久化存储 代码: 爬虫文件: from scrapy.linkextractors ...

  8. TCP协议中URG和PSH位

    URG(紧急位):设置为1时,首部中的紧急指针有效:为0时,紧急指针没有意义. PSH(推位):当设置为1时,要求把数据尽快的交给应用层,不做处理 通常的数据中都会带有PSH但URG只在紧急数据的时设 ...

  9. C语言小总结

    1.函数 有时程序中要多次实现某一功能,就需要多次重复编写实现此功能的代码,这使程序不精练.因此需要模块化程序设计的思想. 函数的返回值要匹配,若函数有返回值可以不接受,但是函数没有返回值不能接受. ...

  10. suid, sgid,粘滞位,chattr

    一. 基本含义和作用 1. SUID:当设置了SUID 位的文件被执行时,该文件将以所有者的身份运行,也就是说无论谁来执行这个文件,他都有文件所有者的特权. 2. SGID:与上面的内容类似.用于设置 ...