博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Controller层设置AOP
阅读量:6926 次
发布时间:2019-06-27

本文共 9267 字,大约阅读时间需要 30 分钟。

近期公司需要做一个web项目,项目中有需求是需要记录特定管理员的操作。操作属性包括:操作时间、操作人、触发数据量等。

自然而然的就想到了面向切面编程(AOP)

项目初步的技术选型是:

Intellij idea+gradle+spring+spring security+hibernate+spring aop+jsp完成项目需求。

项目结构图如下所示:

img_032eb9ffcde5303c081408e9ac4054f4.png
项目结构图

项目创建初期没有web.xml设置如下:

file->project structs->facets->web->Deployment Descriptors->
注意创建的web.xml存在位置与上图中的项目结构图是对应的。

1.各配置文件:##


1.1 build.gradle 脚本文件

group 'com.fxmms'version '1.0-SNAPSHOT'apply plugin: 'java'apply plugin: 'idea'apply plugin: 'war'sourceCompatibility = 1.8repositories {    mavenLocal()    maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }    maven { url "http://repo.maven.apache.org/maven2/"}    mavenCentral()}dependencies {    testCompile group: 'junit', name: 'junit', version: '4.12'    // servlet-api    compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'    //spring相关    compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.3.RELEASE'    compile group: 'org.springframework', name: 'spring-orm', version: '4.3.3.RELEASE'    compile group: 'org.springframework', name: 'spring-aspects', version: '4.3.3.RELEASE'    //hibernate jpa相关    compile group: 'org.jboss.spec.javax.transaction', name: 'jboss-transaction-api_1.2_spec', version: '1.0.1.Final'    compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.2.2.Final'    //c3p0连接池    compile group: 'org.hibernate', name: 'hibernate-c3p0', version: '5.2.2.Final'    //ehcahe二级缓存    compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.2.Final'    //mysql    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.39'    //springData    compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.10.3.RELEASE'}

1.2 web.xml

contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
CharacterEncodingFilter
/*
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
OpenEntityManagerInViewFilter
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
OpenEntityManagerInViewFilter
/*
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:dispatcher-servlet.xml
1
springDispatcherServlet
/

1.3 Spring 配置文件-applicationContext.xml

org.hibernate.cfg.ImprovedNamingStrategy
update
true
true
org.hibernate.dialect.MySQL5InnoDBDialect
true
org.hibernate.cache.ehcache.EhCacheRegionFactory
true

1.4 Spring mvc配置文件-dispatcher-servlet.xml


**1.5 数据库连接文件jdbc-db.properties **

jdbc.user=rootjdbc.password=jdbc.driverClass=com.mysql.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql://localhost/fxmms?useUnicode=true&characterEncoding=UTF-8jdbc.initPoolSize=5jdbc.maxPoolSize=20

1.6 aspect包中切面(封装横切关注点)文件- LogAnnotationAspect.java

package com.fxmms.aspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;/** * Created by mark on 16/10/31. * 日志切面类 */@Aspectpublic class LogAnnotationAspect {    @SuppressWarnings("unused")    //定义切入点    @Pointcut("execution(* com.fxmms.controller.*.*(..))")    private void allMethod() {    }    //针对指定的切入点表达式选择的切入点应用前置通知    @Before("execution(* com.fxmms.controller.*.*(..))")    public void before(JoinPoint call) {        String className = call.getTarget().getClass().getName();        String methodName = call.getSignature().getName();        System.out.println("【注解-前置通知】:" + className + "类的"                + methodName + "方法开始了");    }    //访问命名切入点来应用后置通知    @AfterReturning("allMethod()")    public void afterReturn() {        System.out.println("【注解-后置通知】:方法正常结束了");    }    //应用最终通知    @After("allMethod()")    public void after() {        System.out.println("【注解-最终通知】:不管方法有没有正常执行完成,"                + "一定会返回的");    }    //应用异常抛出后通知    @AfterThrowing("allMethod()")    public void afterThrowing() {        System.out.println("【注解-异常抛出后通知】:方法执行时出异常了");    }    //应用周围通知    //@Around("allMethod()")    public Object doAround(ProceedingJoinPoint call) throws Throwable {        Object result = null;        this.before(call);//相当于前置通知        try {            result = call.proceed();            this.afterReturn(); //相当于后置通知        } catch (Throwable e) {            this.afterThrowing();  //相当于异常抛出后通知            throw e;        } finally {            this.after();  //相当于最终通知        }        return result;    }}

1.7 dao包中数据库访问文件-AccountDao.java

package com.fxmms.dao;import org.springframework.stereotype.Component;/** * Created by mark on 16/10/31. */@Componentpublic class AccountDao {    public void save(String loginname, String password) {        //Do data access        System.out.println("进行数据操作");    }}

1.8 业务逻辑层(service)-AccountService.java 其中注入AccountDao.java

package com.fxmms.service;import com.fxmms.dao.AccountDao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;/** * Created by mark on 16/10/31. */@Componentpublic class AccountService {    @Autowired    private AccountDao accountDao;    public void save(String loginname, String password) {        accountDao.save(loginname, password);        /*throw new RuntimeException("故意抛出一个异常。。。。");*/    }}

**1.9 Controller层 IndexController.java 其中注入AccountService.java **

package com.fxmms.controller;import com.fxmms.service.AccountService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;/** * Created by mark on 16/10/31. */@Controllerpublic class IndexController {    @Autowired(required = true)    AccountService accountService;    @RequestMapping("/index")    public String index() {        accountService.save("张晓","asdasdas");        return "index";    }}

2.测试用例


采用junit进行单元测试

代码如下:

import com.fxmms.controller.IndexController;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * Created by mark on 16/10/31. */public class SpringAopTest {    @Test    public void inteceptorTest() {        ApplicationContext ctx = new ClassPathXmlApplicationContext("dispatcher-servlet.xml");        IndexController bean = (IndexController) ctx.getBean("indexController");        bean.index();    }}

运行结果:

【注解-前置通知】:com.fxmms.controller.IndexController类的index方法开始了进行数据操作【注解-最终通知】:不管方法有没有正常执行完成,一定会返回的【注解-后置通知】:方法正常结束了

总结:


当需要在Controller层设置AOP时,那么需要将 <aop:aspectj-autoproxy proxy-target-class="true"/> 配置到dispatcher-servlet.xml(MVC文件当中)当中并且设置包扫描规则为"use-default-filters="true"

将横切关注点封装为切面,切面中方法的注入是根据切点表达式来决定的。

博客搬家:

欢迎评论哦~

转载地址:http://mbjjl.baihongyu.com/

你可能感兴趣的文章
banq、J道——相见恨晚!
查看>>
Android SDK的docs访问速度很慢
查看>>
胡烁学记:技术开发行业7种典型客户的谈单应对技巧
查看>>
JSON简单例子
查看>>
初学安全
查看>>
es SynonymTokenFilterFactory 源码
查看>>
dubbo -搭建监控中心
查看>>
mysql日志管理
查看>>
k8s dashboard 认证配置
查看>>
CPU简介
查看>>
接口调用
查看>>
Oracle-压缩数据
查看>>
Windows DOS 命令大全
查看>>
安装epel源后,报错Error: Cannot retrieve metalink for repository: epel. Please verify its path.....
查看>>
我的友情链接
查看>>
python的闭包、装饰器和lambda等(笔记)
查看>>
获得指定分类下的商品:assign_cat_goods()
查看>>
laravel artisan 命令列表
查看>>
存储过程
查看>>
Confluence 6 编辑自定义 Decorators
查看>>