• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > 详解spring面向切面aop拦截器

详解spring面向切面aop拦截器

作者:涂宗勋 字体:[增加 减小] 来源:互联网 时间:2017-05-28

涂宗勋 通过本文主要向大家介绍了spring aop切面,spring aop详解,spring aop配置详解,spring aop原理详解,spring ioc和aop等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

spring中有很多概念和名词,其中有一些名字不同,但是从功能上来看总感觉是那么的相似,比如过滤器、拦截器、aop等。
过滤器filter、spring mvc拦截器Interceptor 、面向切面编程aop,实际上都具有一定的拦截作用,都是拦截住某一个面,然后进行一定的处理。

在这里主要想着手的是aop,至于他们的比较,我想等三个都一一了解完了再说,因此这里便不做过多的比较。

在我目前的项目实践中,只在一个地方手动显示的使用了aop,那便是日志管理中对部分重要操作的记录。

据我目前所知,aop拦截一般都是用在具体的方法上,或者说是具体的某一类方法,我所用过的实现方式有两种,一种是直接代码声明,一种是在xml文件中配置。

由于我目前实际开发的项目都是使用spring+spring mvc的架构,然后使用maven管理,然后junit测试。因此我自己几乎所有的个人项目也都是采用这些架构和项目管理工具,在这个理解aop的小项目中,自然也是这样,依赖包如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>springTest</groupId>
 <artifactId>aopTest</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.0.3.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.0.3.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.0.3.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.4</version>
  </dependency>
 </dependencies>
</project>

</div>

第一种方式,Java代码声明:

这里实例中,我要声明一个aop来拦截dao层中的get开头的所有方法,首先建一个dao以及简单的额imp实现:

dao接口如下:

package com.ck.aopTest.dao;
import com.ck.aopTest.model.UserModel;

public interface MyAopDao {
  public void getUser();
  public void getName(UserModel user);
  public void addUser();
}
</div>

简单的实现:

package com.ck.aopTest.dao.impl;
import org.springframework.stereotype.Repository;
import com.ck.aopTest.dao.MyAopDao;
import com.ck.aopTest.model.UserModel;

@Repository
public class MyAopDaoImpl implements MyAopDao {

  @Override
  public void getUser() {
    System.out.println("这是我的aop测试dao方法一");
  }
  @Override
  public void getName(UserModel userModel) {
    System.out.println("这是我的aop测试dao方法二");
  }
  @Override
  public void addUser() {
    System.out.println("这是我的aop测试dao方法三");
  }
}

</div>

然后声明一个aop:

package com.ck.aopTest.aop;
import java.util.Date;
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;
import com.ck.aopTest.model.UserModel;

@Aspect
@Component
public class MyAop {

  @Pointcut("execution(public * com.ck.aopTest.dao.impl.*.get*(..))")
  private void aopTest() {

  }
  @Before("aopTest()")
  public void before() {
    System.out.println("调用dao方法前拦截" + new Date().getTime());
  }
  @After("aopTest()" + "&&args(user)")
  public void after(UserModel user) {
    System.out.println(user.getName());
    System.out.println("调用dao方法之后拦截" + new Date().getTime());
  }
  @Around("aopTest()")
  public void around(ProceedingJoinPoint pdj) {
    System.out.println("调用dao之前的环绕拦截" + new Date().getTime());
    try {
      pdj.proceed();
    } catch (Throwable e) {
      e.printStackTrace();
    }
    System.out.println("调用dao之后的环绕拦截" + new Date().getTime());
  }
}

</div>

上述代码便是用java声明aop的核心代码,其中注解@Aspect的作用的就是告诉spring这是一个aop类,然后@Component就不用多说了,告诉spring这是一个需要扫描的类。

再往下,@Pointcut(“execution(public * com.ck.aopTest.dao.impl..get(..))”)正式声明需要拦截的切面,@Pointcut以及后边的额execution是固定的写法,execution后括号内的内容便是具体的切面,这里的意思是拦截所有public的任何返回值或者void的、命名空间是com.ck.aopTest.dao.impl下边的所有的类中的所有get开头的拥有任意多个参数的方法。

简单点说也就是当任何调用了com.ck.aopTest.dao.impl这个包中任何类中的get开头的方法,便会激活这个aop。

而紧接着上边这一段,我们看到了一个private void aopTest() 空的方法,实际上这个方法的作用是为这个aop切面声明一个名字,便于使用,也便于在多个aop切面时正常区分。

再后边的@Before、@After、@Around便是三个可选拦截方式,见名之意,分别是在上边声明的切面指明的方法调用之前执行、调用之后执行、以及环绕执行,调用之前和调用之后比较好理解,环绕的意思是在调用之前和之后都执行一定的逻辑。
从代码中可以看出,pdj.proceed();之前和之后各打印了两行数据,pdj.proceed();就代表了继续执行,如果是了解filter的应该很容易想到这个方法实际上和chain.doFilter很像,可以理解成放行。

在这三个注解之后需要指定要使用的切面,即@Pointcut声明的切面,指定名称就行。

从代码中可以看到有一个地方后边加了“&&args(UserModel user)”,意思是指定形参,也就是说指定的切面中有效方法的参数,例如上边dao中的getName方法有一个UserModel类型的参数,这里便可以使用。

主要代码写好了,接下来还有个必不可少的步骤,既然是spring项目,是spring的aop,那么自然需要配置spring文件,指明需要spring管理的包:

<?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" " 
  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"> 
  <context:component-scan base-package="com.ck.aopTest.*" />
</beans>

</div>

为了验证这里的aop是否真的有效,我写了一个junit测试:

package com.ck.aopTest.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.ck.aopTest.dao.MyAopDao;
import com.ck.aopTest.model.UserModel;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class AopTest {
  @Autowired
  private MyAopDao myAopDao;

  @Test
  public void aopTest2() {
    UserModel user = new UserModel();
    myAopDao.getName(user);
  }
}
</div>

按理说,这里运行测试方法后应该打印出很多条输出,但是遗

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 详解spring面向切面aop拦截器

相关文章

  • 2017-05-28java 自己实现DataSource实现实例
  • 2017-05-28Eclipse智能提示及快捷键
  • 2017-05-28java 中同步、异步、阻塞和非阻塞区别详解
  • 2017-05-28Java 归并排序算法、堆排序算法实例详解
  • 2017-05-28JFileChooser实现对选定文件夹内图片自动播放和暂停播放实例代码
  • 2017-05-28详解SpringBoot Schedule配置
  • 2017-05-28java 中使用maven shade plugin 打可执行Jar包
  • 2017-05-28Java根据模板导出Excel报表并复制模板生成多个Sheet页
  • 2017-05-28spring boot装载自定义yml文件
  • 2017-05-28Java中finalize()详解及用法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • java实现留言板功能实例
    • 全面掌握Java内部类
    • Java中的 FilterInputStream简介_动力节点Java学院整理
    • HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
    • Map获取键值,Map的几种遍历方法总结(推荐)
    • HashMap工作原理_动力节点Java学院整理
    • Java 中的 DataInputStream 介绍_动力节点Java学院整理
    • Java编程基本概念
    • Java中反射动态代理接口的详解及实例
    • java连接Access数据库的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有