Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Spring核心概念之AOP

一、AOP 的概念

AOP(Aspect Oriented Programming)的缩写,面向切面编程,主要作用就是对代码进行增强处理。理解面向切面编程的含义:就是在不改变原有程序的基础上为代码增加新的功能。实现面向切面编程需要了解两个概念:>切入点:可以插入增强处理的方法,比如原对象的fun()方法。>增强处理类型:在原对象fun()方法之前还是之后插入新功能。

二、Spring AOP简单应用

1.新建一个java项目2.到官网下载Spring AOP和AspectJ框架所需要的jar包,并将下载所需的jar文件添加到项目中。3.在项目中添加User实体类
1234567891011121314151617181920package com.jbit.fsd.entity; public class User {     private int id;    private String username;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }     }
4.添加数据访问层接口和实现类,并添加相应的方法
123456789101112package com.jbit.fsd.dao; import java.util.List; import com.jbit.fsd.entity.User;// 数据访问层接口public interface UserDao {     public List<User> getAll();         public void addUser(User user);}
实现类:
1234567891011121314151617181920212223242526package com.jbit.fsd.dao.impl; import java.util.ArrayList;import java.util.List; import com.jbit.fsd.dao.UserDao;import com.jbit.fsd.entity.User; public class UserDaoImpl implements UserDao {     @Override    public List<User> getAll() {        //操作数据库读到所有数据        List<User> list=new ArrayList<User>();        list.add(new User());        list.add(new User());        list.add(new User());        return list;    }     @Override    public void addUser(User user) {        System.out.println("添加成功");    } }
5.添加业务处理层接口和实现类
123456789101112131415package com.jbit.fsd.service; import java.util.List; import com.jbit.fsd.dao.UserDao;import com.jbit.fsd.entity.User; public interface UserService {     public List<User> getAll();         public void addUser(User user);          }
实现类:
123456789101112131415161718192021222324252627package com.jbit.fsd.service.impl; import java.util.List; import com.jbit.fsd.dao.UserDao;import com.jbit.fsd.entity.User;import com.jbit.fsd.service.UserService; public class UserServiceImpl implements UserService{    private UserDao dao;    //通过spring注入进来    public void setDao(UserDao dao) {        this.dao = dao;    }     @Override    public List<User> getAll() {        System.out.println("正在执行添加用户的业务!");        return dao.getAll();    }     @Override    public void addUser(User user) {<br>                System.out.println("正在执行添加用户的业务!");        dao.addUser(user);    } }
6.添加AOP增强处理类
123456789101112package com.jbit.fsd.aop; import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory; public class ServiceLoging {    private Log log = LogFactory.getLog(this.getClass());     public void beforeService(){        log.info("aop方法被调用!");    }}
7.在src目录下新建applicationContext.xml文件
1234567891011121314151617181920212223242526272829303132<?xml version="1.0" encoding="UTF-8"?> <!--  - Application context definition for JPetStore"s business layer.  - Contains bean references to the transaction manager and to the DAOs in  - dataAccessContext-local/jta.xml (see web.xml"s "contextConfigLocation").  --><beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        <span style="color: rgb(255, 0, 0);">xmlns:aop="http://www.springframework.org/schema/aop"</span>        xmlns:tx="http://www.springframework.org/schema/tx"        xsi:schemaLocation="            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd            <span style="color: rgb(255, 0, 0);">http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd</span>            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">        <!-- 以面向接口思想编程实现解耦和 -->    <bean id="userDao" class="com.jbit.fsd.dao.impl.UserDaoImpl">    </bean>    <bean id="userServiceImpl" class="com.jbit.fsd.service.impl.UserServiceImpl">        <property name="dao" ref="userDao"></property>  <!-- 属性注入 -->    </bean>    <!-- 配置切面 -->    <bean id="serviceLogging" class="com.jbit.fsd.aop.ServiceLoging"></bean>    <aop:config>        <!-- 配置切入点 -->        <aop:pointcut expression="execution(public void  addUser(com.jbit.fsd.entity.User))" id="servicePointcut"/>        <!-- 将切面和切入点编制在一起-->        <aop:aspect ref="serviceLogging">            <aop:before method="beforeService" pointcut-ref="servicePointcut"/>        </aop:aspect>    </aop:config></beans>
8.main方法测试:
12345678910111213141516171819202122232425package com.jbit.fsd.test; import java.util.List; import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; import com.jbit.fsd.dao.UserDao;import com.jbit.fsd.entity.User;import com.jbit.fsd.printer.Printer;import com.jbit.fsd.service.UserService;import com.jbit.fsd.service.impl.UserServiceImpl; public class Test {     /**     * @param args     */    public static void main(String[] args) {        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");        UserService dao=(UserService) ac.getBean("userServiceImpl");        dao.addUser(new User());    } }
说明:1.在.xml文件中需要添加aop命名空间,导入与aop配置相关的标签。2.AOP相关的配置在<aop:config>标签中,切入点的配置在<aop:pointcut>标签中。3.execution是切入点的标识符,括号是切入点的表达式,配置需要增强的方法。4.切入点表达式常用几种模糊匹配方式:>public * addUser(com.able.entity.User),“*”表示配置所有类型的返回值。>public void * (com.able.entity.User), "*"代表匹配所有的方法名。>public void addUser(..),  " .. "表示匹配所有参数个数和类型。> * com.able.service.*.*( . . ),  表示匹配com.able.service包下面所有类的所有方法。> * com.able.service . . *(), 表示匹配com.able.service包以及子包下所有类的所有方法。

三、增强处理类型简介

1.前置增强处理特点:在目标方法前织入增强处理。<aop:before method="beforeService" poontcut-ref="servicePointcut"/>如果想在这个方法中获得切入点的信息,使用如下方法:
1234567891011121314151617package com.jbit.fsd.aop; import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.aspectj.lang.JoinPoint; public class ServiceLoging {    private Log log = LogFactory.getLog(this.getClass());     public void beforeService(JoinPoint joinPoint){        System.out.println("aop方法被调用");        System.out.println("连接点对象:"+joinPoint.getTarget().getClass().getSimpleName());        System.out.println("连接点方法:"+joinPoint.getSignature());        System.out.println("连接点方法参数:"+joinPoint.getArgs()[0]);             }}
2.后置增强处理特点:在目标方法正常执行(不出现异常)后织入增强处理。<aop:after-returning method="afterReturning" pointcut-ref="servicePointcut"/>如果需要获取返回值,添加returning="returnVal"<aop:after-returning method="aft" pointcut-ref="ser" returning="returnVal"/>
123public void afterService(Object returnVal){        System.out.println(returnVal);    }
3.异常增强处理特点:在目标方法出现异常后织入增强处理。<aop:after-throwing mehod=" " pointcut-ref=" " throwing ="ex"/>如果需要获取异常对象才添加throwing="ex"
123public void afterThrowing(Exception ex){        System.out.println(ex.getMessage());    }
4.最终增强处理特点:不论方法是否抛异常,都会在目标方法最后织如增强处理,类似与finally。<aop:after method="after" pointcut-ref="servicePointcut"/>5.环绕增强处理特点:在目标方法的前后都可以织入增强处理。<aop:around method="" pointcut-ref="" />
123456789public Boolean around(ProceedingJoinPoint pjp) throws Throwable{        System.out.println("目标方法的参数:"+pjp.getArgs()[0]);        Boolean b = null;        if true) {            b = (Boolean) pjp.proceed(pjp.getArgs());        }        return b;             }

四、使用AspectJ 简化AOP配置

Spring的AOP配置常有两种方式:>通过schema形式实现简单AOP配置,也就是上面事例使用方法。>使用annotation简化AOP配置。AspectJ是一个面向切面的框架,AspectJ定义了AOP语法。使用@AspectJ必须使用jdk5.0以上版本。步骤:1.编写业务类(与上面方法相同)。2.编写切面类。
1234567891011121314151617181920212223242526package com.jbit.ssh.aop; import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before; @Aspect    //1.通过注解标记一个切面public class AspectTest {         @Before"execution(* com.jbit.ssh.service..*.*(..))"//2.定义切点和增强类型(切点表达式)    public void ba(){  //3.增强处理的fun 4.配置xml        System.out.println("前置增强-------");    }    @After"execution(* com.jbit.ssh.service..*.*(..))"    public void aa(){        System.out.println("后置增强------");    }    /**     * @before表示前置增强     * @AfterReturning:表示后置增强处理     * @Around:表示环绕增强处理     * @AfterThrowing:表示异常增强处理     * @After:表示最终增强处理     */ }
3.编写配置文件实现AOP
123456789101112131415161718192021222324<?xml version="1.0" encoding="UTF-8"?> <!--  - Application context definition for JPetStore"s business layer.  - Contains bean references to the transaction manager and to the DAOs in  - dataAccessContext-local/jta.xml (see web.xml"s "contextConfigLocation").  --><beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        <span style="color: rgb(255, 0, 0);">xmlns:aop="http://www.springframework.org/schema/aop"</span>        xmlns:tx="http://www.springframework.org/schema/tx"        xmlns:p="http://www.springframework.org/schema/p"        xmlns:context="http://www.springframework.org/schema/context"        xsi:schemaLocation="            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd            <span style="color: rgb(255, 0, 0);">http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd</span>            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" >           <!--4.基于@AspectJ切面的驱动器 -->    <aop:aspectj-autoproxy />    <bean class="com.jbit.ssh.aop.AspectTest"></bean></beans>
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-07/133259.htm