spring项目中aop的使用

  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();
    }
}

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

原文地址:https://www.cnblogs.com/hhhshct/p/9450660.html

时间: 2024-11-10 01:08:51

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

spring boot 中AOP的使用

一.AOP统一处理请求日志 也谈AOP 1.AOP是一种编程范式 2.与语言无关,是一种程序设计思想 面向切面(AOP)Aspect Oriented Programming 面向对象(OOP)Object Oriented Programming 面向过程(POP) Procedure Oriented Programming 再谈AOP 1.面向过程到面向对象 2.换个角度看世界,换个姿势处理问题 3.将通用逻辑从业务逻辑中分离出来 二.处理过程 个人理解,其实就是日志体系为了方便使用,可以

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

什么是WebService?webService小示例 点此了解 下面进入正题: Javaweb项目(spring项目)中集成webservice ,实现对外开放接口步骤: 准备: 采用与spring兼容性较好的cxf来实现 cxf 的  jar下载地址: http://cxf.apache.org/download.html 选择zip格式下载,解压后的lib目录下的jar 需要最少的jar如下: cxf-2.3.3.jargeronimo-annotation_1.0_spec-1.1.1.

使用junit4测试spring项目中service方法

使用junit4测试项目中service方法 1 import java.util.HashMap; 2 import java.util.List; 3 import java.util.Map; 4 5 import javax.annotation.Resource; 6 7 import org.junit.Test; 8 import org.junit.runner.RunWith; 9 import org.springframework.test.context.ContextC

在spring项目中,普通类注入获取Bean,实现ApplicationContextAware接口

在平时spring项目中,某个不能注入Bean的项目中要获取Bean. @Component public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext = null; public SpringUtil() { } public void setApplicationContext(ApplicationContext arg0

在Spring项目中使用@Scheduled注解定义简单定时任务

如题所示,有时候我们需要在Web项目中配置简单的定时任务,而且因为任务并不复杂不想使用定时调度框架(PS:Quartz.ActiveMQ .Kafka等),这时就可以考虑使用@Scheduled注解来定义简单的定时任务.其全部配置如下: (1)在Spring的配置文件中添加定时任务相关配置: xml配置的头文件中添加: xmlns:task="http://www.springframework.org/schema/task" 以及在xsi:schemaLocation中添加: ht

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

A模块和B模块都分别拥有自己的Spring XML配置,并分别拥有自己的配置文件: A模块 A模块的Spring配置文件如下: Xml代码   <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSch

spring项目中web-inf下不能引用页面资源

1.spring项目结构 2.spring结构说明 web-inf目录是不对外开放的,外部没办法直接访问到(即通过url访问),只有通过映射来访问,如映射一个action或servlet通过服务器端跳转来访问到具体的页面,这样可以限制访问,提高安全性 页面资源文件只能放在webapp文件下,若css.js.image等文件放在web-inf下是引用不了的

spring 项目中使用 hibernate validator验证输入参数

1 hibernate validator 官方文档:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/ 在 springboot 项目中 spring-boot-starter-web 已经包含了 hibernate-validator 可以直接使用.否则需要在 maven 依赖中添加依赖项. <dependency> <groupId>org.hibernate.valid

项目中AOP的实例应用

其中包括了权限管理.表单验证.事务管理.信息过滤.拦截器.过滤器.页面转发等等. 公司项目的应用:(涉及用户验证登录以及用户是否有管理员权限.心理用户权限等),还有涉及的其他日志管理代码就不一一举例了: /** * 登录拦截器(登录判断) * @author alex * */ public class LoginInterceptor extends HandlerInterceptorAdapter { @Autowired private UserService userService;