Spring AOP

AOP
    1.将散布在系统中的公共功能,提取封装成独立的模块
    2.采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能

先对Spring AOP里面几个名词进行说明。

  • 切面(Aspect)
    • 通知和切点的结合  
    • 切面使用通用类或者在普通类中加@AspectJ
  • 连接点(Join point)
    • 应用执行中插入切面的一个点
    • 调用方法,抛出异常,修改字段 
    • 方法执行 
  • 通知(Advice)
    • 切面的工作  
  • 切入点(Pointcut)
    • 匹配通知要织入的一个(以上)连接点
    • 类名,方法名指定  
  • 引入(Introduction)
    • 向现有类添加方法或属性  
  • 目标对象(Target Object)
    • 被一个(以上)切面通知的对象
    • 代理类  
  • 织入(Weaving)
    • 切面应用到目标对象,创建新的代理对象
    • 编译期,类加载期,运行期织入  

目的
    1.A从系统中分离出切面,独立于业务逻辑实现,在程序执行时织入程序中运行

  • 切面,可重用的公共模块,比如,日志,事务等

    2.配置AOP主要使用aop命名空间下的元素完成。可以实现定义切入点和织入增强等操作

    3.Spring提供的增强处理类型包括:前置增强、后置增强、环绕增强、异常抛出增强、最终增强等

作用
    1.实现系统日志功能
        a.业务介绍:将业务逻辑方法的调用信息输出到控制台
        b.AOP思路:分别编写业务逻辑代码和“增强”代码,运行时再组装
        c.步骤:
            1)添加jar包
            2)编写业务逻辑接口和实现类,编码时无需关心其他功能
        d.定义切入点
            1)public * addUser(com.xuetang9.demo.entity.User)
            2)public void *(com.xuetang9.demo.entity.User)
            3)public void addUser(..)                        不知道参数类型
            4)* com.xuetang9.demo.service.*.*(..)            service包所有的方法
            5)* com.xuetang9.demo.service..*.*(..)  等        service包及其子包所有的方法

    2.增强类型
        a.异常抛出增强:目标方法抛出异常时织入增强处理
            ThrowsAdvice接口中并没有定义任何方法,但是我们在定义异常抛出的增强方法时必须遵守以下方法签名:
            void afterThrowing ( [Method method, Object[] arguments, Object target) Throwable ex )
        注意:方法名必须是afterThrowing。方法的入参只有最后一个是必须的,前三个入参是可选的,但是前三个参数要么都提供,要么一个也不提供。正确的声明方法举例:
            1)afterThrowing(Method method, Object[] args, Object target, SQLException ex)
            2)afterThrowing(SQLException ex)
            3)afterThrowing(RuntimeException ex)
            错误的声明方法举例:
                1)catchThrowing(RuntimeException ex):方法名错误
                2)afterThrowing(Method method, RuntimeException ex):参数列表错误

        b.环绕增强:在目标方法的前后都可以织入增强处理
            1)功能最强大的增强处理,Spring把目标方法的控制权全部在它手中
            2)可以获取或修改目标方法的参数、返回值。可以对它进行异常处理,甚至可以决定目标方法是否执行
        c.前置增强
        d.后置增强
        e.最终增强

范例:
1.实体类及其配置文件
a.实体类 -- User类

 1 package com.Elastic.SpringDemo2.ivy.entity;
 2 
 3 import java.io.Serializable;
 4 
 5 public class User implements Serializable {
 6     private String loginName;
 7     private String loginPass;
 8     
 9     public String getLoginName() {
10         return loginName;
11     }
12     public void setLoginName(String loginName) {
13         this.loginName = loginName;
14     }
15     public String getLoginPass() {
16         return loginPass;
17     }
18     public void setLoginPass(String loginPass) {
19         this.loginPass = loginPass;
20     }
21     
22 }


b.实体类配置文件 -- User.hbm.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2016-7-5 22:38:24 by Hibernate Tools 3.4.0.CR1 -->
 5 <hibernate-mapping>
 6     <class name="com.Elastic.SpringDemo2.ivy.entity.User" table="user">
 7         <id name="loginName" type="java.lang.String">
 8             <column name="userName" />
 9             <generator class="assigned" />
10         </id>
11         <property name="loginPass" type="java.lang.String">
12             <column name="passWord" />
13         </property>
14     </class>
15 </hibernate-mapping>


2.hibernate配置文件 -- hibernate.cfg.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 8         <property name="hibernate.connection.password">root</property>
 9         <property name="hibernate.connection.url">jdbc:mysql://localhost/hibernatedb</property>
10         <property name="hibernate.connection.username">root</property>
11         <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
12  
13           <property name="show_sql">true</property>
14           <property name="format_sql">true</property>
15  
16           <mapping resource="com/Elastic/SpringDemo2/ivy/entity/User.hbm.xml"/>
17     </session-factory>
18 </hibernate-configuration>


3.util包
a.HibernateUtil类

 1 package com.Elastic.SpringDemo2.ivy.util;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.cfg.Configuration;
 6 public final class HibernateUtil {
 7     private static Configuration cfg = null;
 8     private static SessionFactory sessionFactory = null;
 9     
10     //本地线程
11     public static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
12     
13     static{
14         cfg = new Configuration().configure();
15         sessionFactory = cfg.buildSessionFactory();
16     }
17     
18     public static Session getSession(){
19         Session session = threadLocal.get();
20         if (null == session || !session.isOpen()) {
21             session = sessionFactory.openSession();
22             threadLocal.set(session);
23         }
24         return session;
25     }
26 }


4.dao包
a.IBaseDao接口

  1 package com.Elastic.SpringDemo2.ivy.dao;
  2 
  3 import java.io.Serializable;
  4 import java.util.List;
  5 import java.util.Map;
  6 
  7 import org.hibernate.Session;
  8 import org.hibernate.criterion.DetachedCriteria;
  9 public interface IBaseDao<T> {
 10     /**
 11      *
 12      * <p>
 13      * <h3>方法功能描述:获取Session对象</h3>
 14      * </p>
 15      * @return
 16      * @procedure 执行过程
 17      * @see IBaseDao
 18      */
 19     Session getSession();
 20     
 21     /**
 22      *
 23      * <p>
 24      * <h3>方法功能描述:保存数据</h3>
 25      * </p>
 26      * @param record    需要保存的对象
 27      * @procedure 执行过程
 28      * @see IBaseDao
 29      */
 30     void save(T record);
 31     
 32     /**
 33      *
 34      * <p>
 35      * <h3>方法功能描述:根据主键删除对应的数据</h3>
 36      * </p>
 37      * @param id
 38      * @procedure 执行过程
 39      * @see IBaseDao
 40      */
 41     //不明确id的类型,就用Serializable
 42     void delete(Serializable id);
 43     
 44     /**
 45      *
 46      * <p>
 47      * <h3>方法功能描述:根据数据对象删除数据库中对应的数据</h3>
 48      * </p>
 49      * @param record
 50      * @procedure 执行过程
 51      * @see IBaseDao
 52      */
 53     void delete(T record);
 54     
 55     /**
 56      *
 57      * <p>
 58      * <h3>方法功能描述:根据指定的对象修改对应的数据</h3>
 59      * </p>
 60      * @param record
 61      * @procedure 执行过程
 62      * @see IBaseDao
 63      */
 64     void update(T record);
 65     
 66     /**
 67      *
 68      * <p>
 69      * <h3>方法功能描述:根据主键查询对应的数据</h3>
 70      * </p>
 71      * @param id
 72      * @return 返回查找到的数据,如果没有返回null
 73      * @procedure 执行过程
 74      * @see IBaseDao
 75      */
 76     T findById(Serializable id);
 77     
 78     /**
 79      *
 80      * <p>
 81      * <h3>方法功能描述:根据指定的hql语句和参数查询语句</h3>
 82      * </p>
 83      * @param hql  需要执行的查询的HQL语句
 84      * @param params  执行的查询的HQL语句所需的参数,如果没有填写null
 85      * @return    返回查询数据的集合,如果出现异常返回null
 86      * @procedure 执行过程
 87      * @see IBaseDao
 88      */
 89     List<T> find(String hql,Map<String, Object> params);
 90     
 91     /**
 92      *
 93      * <p>
 94      * <h3>方法功能描述:根据指定的HQL语句和参数以及分页所需的数据执行查询</h3>
 95      * </p>
 96      * @param hql   需要执行的查询的HQL语句
 97      * @param pageIndex    需要查询的页数
 98      * @param pageSize    每页显示的数据条数
 99      * @param params    执行的查询的HQL语句所需的参数,如果没有填写null
100      * @return    返回分页查询的结果,是一个Map对象,该对象包含<blockquote>
101      *        <b>data</b>:查询结果的数据集合是一个List对象<br>
102      *         <b>pageIndex</b>:当前查询的页数<br>
103      *         <b>pageSize</b>:每页显示的数据条数<br>
104      *         <b>total</b>:数据的总条数<br>
105      *         <b>pageTotal</b>:数据的总页数<br>
106      *         <b>hasPrev</b>:是否有上一条数据<br>
107      *         <b>hasNext</b>:是否有下一条数据<br>
108      *         </blockquote>
109      * @procedure 执行过程
110      * @see IBaseDao
111      */
112     Map<String, Object> find(String hql, int pageIndex, int pageSize, Map<String, Object> params);
113     
114     /**
115      *
116      * <p>
117      * <h3>方法功能描述:分页查询数据</h3>
118      * </p>
119      * @param pageIndex    需要查询的页数
120      * @param pageSize    每页显示的数据条数
121      * @return    返回分页查询的结果,是一个Map对象,该对象包含<blockquote>
122      *        <b>data</b>:查询结果的数据集合是一个List对象<br>
123      *         <b>pageIndex</b>:当前查询的页数<br>
124      *         <b>pageSize</b>:每页显示的数据条数<br>
125      *         <b>total</b>:数据的总条数<br>
126      *         <b>pageTotal</b>:数据的总页数<br>
127      *         <b>hasPrev</b>:是否有上一条数据<br>
128      *         <b>hasNext</b>:是否有下一条数据<br>
129      *         </blockquote>
130      * @procedure 执行过程
131      * @see IBaseDao
132      */
133     Map<String, Object> find(int pageIndex, int pageSize);
134     
135     /**
136      *
137      * <p>
138      * <h3>方法功能描述:根据DetachedCriteria 对象设置的条件查询数据,该功能不具备分页操作</h3>
139      * </p>
140      * @param detachedCriteria    需要设置的对象查询条件
141      * @return    返回查询数据的集合,如果出现异常返回null
142      * @procedure 执行过程
143      * @see IBaseDao
144      */
145     List<T> find(DetachedCriteria detachedCriteria);
146 
147     
148     /**
149      *
150      * <p>
151      * <h3>方法功能描述:根据DetachedCriteria 对象设置的条件进行分页查询</h3>
152      * </p>
153      * @param detachedCriteria    需要设置的对象查询条件
154      * @param pageIndex    需要查询的页数
155      * @param pageSize    每页显示的数据条数
156      * @return    返回分页查询的结果,是一个Map对象,该对象包含<blockquote>
157      *        <b>data</b>:查询结果的数据集合是一个List对象<br>
158      *         <b>pageIndex</b>:当前查询的页数<br>
159      *         <b>pageSize</b>:每页显示的数据条数<br>
160      *         <b>total</b>:数据的总条数<br>
161      *         <b>pageTotal</b>:数据的总页数<br>
162      *         <b>hasPrev</b>:是否有上一条数据<br>
163      *         <b>hasNext</b>:是否有下一条数据<br>
164      *         </blockquote>
165      * @procedure 拼接HQL语句
166      * @see IBaseDao
167      */
168     Map<String, Object> find(DetachedCriteria detachedCriteria, int pageIndex, int pageSize);
169     
170     
171     
172 }


b.IBaseDao接口实现类 -- BaseDao

  1 package com.Elastic.SpringDemo2.ivy.dao;
  2 
  3 import java.io.Serializable;
  4 import java.lang.reflect.ParameterizedType;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Map;
  8 
  9 import org.hibernate.Criteria;
 10 import org.hibernate.Query;
 11 import org.hibernate.Session;
 12 import org.hibernate.criterion.DetachedCriteria;
 13 import org.hibernate.criterion.Projections;
 14 
 15 import com.Elastic.SpringDemo2.ivy.util.HibernateUtil;
 16 //忽略警告
 17 @SuppressWarnings({ "rawtypes", "unchecked" })
 18 public class BaseDao<T> implements IBaseDao<T>{
 19     
 20     private Class entityClass;
 21     
 22     public BaseDao(){
 23         entityClass = this.getEntityClass();
 24     }
 25     
 26     /**
 27      *
 28      * <p>
 29      * <h3>方法功能描述:根据反射得到当前泛型参数(实体类)的数据类型</h3>
 30      * </p>
 31      * @return
 32      * @procedure 执行过程
 33      * @see BaseDao
 34      */
 35     private Class getEntityClass(){
 36         try {
 37             ParameterizedType paramsType = (ParameterizedType)this.getClass().getGenericSuperclass();//只能通过父类得到
 38             return (Class)paramsType.getActualTypeArguments()[0];
 39         } catch (Exception e) {
 40             e.printStackTrace();
 41         }
 42         return null;
 43     }
 44     
 45     @Override
 46     public Session getSession() {
 47         return HibernateUtil.getSession();
 48     }
 49 
 50     private Map<String, Object> createPageData(List<T> data, int pageIndex, int pageSize, int total) {
 51         Map<String, Object>  map = new HashMap<String, Object>();
 52         
 53         //获得总页数
 54         int pageTotal = (int)Math.ceil((double)total / pageSize);
 55         map.put("data", data);
 56         map.put("pageIndex", pageIndex);
 57         map.put("pageSize", pageSize);
 58         map.put("total", total);
 59         map.put("pageTotal", pageTotal);
 60         
 61         //boolean,若没赋值,默认true
 62         map.put("hasPrev", pageIndex > 1);
 63         map.put("hasNext", pageIndex < pageTotal);
 64         return map;
 65     }
 66 
 67     /* (non-Javadoc)
 68      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#save(java.lang.Object)
 69      */
 70     @Override
 71     public void save(T record) {
 72         this.getSession().save(record);
 73         
 74     }
 75 
 76     /* (non-Javadoc)
 77      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#delete(java.io.Serializable)
 78      */
 79     @Override
 80     public void delete(Serializable id) {
 81         this.getSession().delete(this.findById(id));
 82         
 83     }
 84 
 85     /* (non-Javadoc)
 86      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#delete(java.lang.Object)
 87      */
 88     @Override
 89     public void delete(T record) {
 90         this.getSession().delete(record);
 91         
 92     }
 93 
 94     /* (non-Javadoc)
 95      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#update(java.lang.Object)
 96      */
 97     @Override
 98     public void update(T record) {
 99         this.getSession().update(record);
100         
101     }
102 
103     /* (non-Javadoc)
104      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#findById(java.io.Serializable)
105      */
106     @Override
107     public T findById(Serializable id) {
108         return (T) this.getSession().get(entityClass, id);
109     }
110 
111     /* (non-Javadoc)
112      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#find(java.lang.String, java.util.Map)
113      */
114     @Override
115     public List<T> find(String hql, Map<String, Object> params) {
116         Query query = this.getSession().createQuery(hql);
117         query.setProperties(params);
118         return query.list();
119     }
120 
121     /* (non-Javadoc)
122      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#find(java.lang.String, int, int, java.util.Map)
123      */
124     @Override
125     public Map<String, Object> find(String hql, int pageIndex, int pageSize, Map<String, Object> params) {
126         String hqlCount;
127         //通过给定的HQL语句查询全部条数
128         int i = hql.indexOf("from");
129         if (i == 0) {
130             hqlCount = "select count(*) " + hql;
131         } else {
132             hqlCount = "select count(*) " + hql.substring(i);
133         }
134         
135         Query query = this.getSession().createQuery(hql);
136         query.setProperties(params);
137         
138         //index从0开始
139         query.setFirstResult((pageIndex - 1) * pageSize);
140         query.setMaxResults(pageSize);
141         
142         int total = Integer.parseInt(this.getSession().createQuery(hqlCount).uniqueResult().toString());
143         return this.createPageData(query.list(), pageIndex, pageSize, total);
144     }
145 
146     /* (non-Javadoc)
147      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#find(int, int)
148      */
149     @Override
150     public Map<String, Object> find(int pageIndex, int pageSize) {
151         Criteria criteria = this.getSession().createCriteria(entityClass);
152         
153         //查询总数
154         criteria.setProjection(Projections.rowCount());
155         int total = Integer.parseInt(criteria.uniqueResult().toString());
156         criteria.setProjection(null);
157         
158         criteria.setFirstResult((pageIndex - 1) * pageSize);
159         criteria.setMaxResults(pageSize);
160         return this.createPageData(criteria.list(), pageIndex, pageSize, total);
161     }
162 
163     /* (non-Javadoc)
164      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#find(org.hibernate.criterion.DetachedCriteria)
165      */
166     public List<T> find(DetachedCriteria detachedCriteria) {
167         return  detachedCriteria.getExecutableCriteria(getSession()).list();
168     }
169 
170     /* (non-Javadoc)
171      * @see com.Elastic.StrutsDemo2.ivy.dao.IBaseDao#find(org.hibernate.criterion.DetachedCriteria, int, int)
172      */
173     @Override
174     public Map<String, Object> find(DetachedCriteria detachedCriteria, int pageIndex, int pageSize) {
175         //查询总数
176         int total = Integer.parseInt(detachedCriteria.getExecutableCriteria(getSession())
177                 .setProjection(Projections.rowCount())
178                 .uniqueResult().toString());
179         
180         //分页查询
181         Criteria criteria = detachedCriteria.getExecutableCriteria(getSession());
182         criteria.setFirstResult((pageIndex - 1) * pageSize);
183         criteria.setMaxResults(pageSize);
184         return this.createPageData(criteria.list(), pageIndex, pageSize, total);
185     }    
186 }


c.具体业务接口 -- UserDao类

1 package com.Elastic.SpringDemo2.ivy.dao;
2 
3 import com.Elastic.SpringDemo2.ivy.entity.User;
4 
5 public interface UserDao extends IBaseDao<User> {
6 
7 }


5.service包
a.业务接口 -- UserService

1 package com.Elastic.SpringDemo2.ivy.service;
2 
3 import com.Elastic.SpringDemo2.ivy.entity.User;
4 
5 public interface UserService {
6     User login(String name, String pass);
7 }


6.dao.impl包
a.接口实现类 -- UserDaoImpl

 1 package com.Elastic.SpringDemo2.ivy.dao.impl;
 2 
 3 import java.io.Serializable;
 4 import java.util.List;
 5 import java.util.Map;
 6 
 7 import org.hibernate.Session;
 8 import org.hibernate.criterion.DetachedCriteria;
 9 
10 import com.Elastic.SpringDemo2.ivy.dao.BaseDao;
11 import com.Elastic.SpringDemo2.ivy.dao.UserDao;
12 import com.Elastic.SpringDemo2.ivy.entity.User;
13 
14 public class UserDaoImpl extends BaseDao<User> implements UserDao {
15 
16 }


7.service.impl包
a.接口实现类 -- UserServiceImpl

 1 package com.Elastic.SpringDemo2.ivy.dao.impl;
 2 
 3 import com.Elastic.SpringDemo2.ivy.dao.UserDao;
 4 import com.Elastic.SpringDemo2.ivy.entity.User;
 5 import com.Elastic.SpringDemo2.ivy.service.UserService;
 6 
 7 public class UserServiceImpl implements UserService {
 8 
 9     private UserDao userDao;
10 
11     public UserDao getUserDao() {
12         return userDao;
13     }
14 
15     public void setUserDao(UserDao userDao) {
16         this.userDao = userDao;
17     }
18 
19     @Override
20     public User login(String name, String pass) {
21         User user = userDao.findById(name);
22         if (null != user && user.getLoginPass().equals(pass)) {
23             return user;
24         }
25         return null;
26     }
27 }


b.异常抛出增强,接口实现类 -- UserServiceImpl

 1 package com.Elastic.SpringDemo2.ivy.dao.impl;
 2 
 3 import com.Elastic.SpringDemo2.ivy.dao.UserDao;
 4 import com.Elastic.SpringDemo2.ivy.entity.User;
 5 import com.Elastic.SpringDemo2.ivy.service.UserService;
 6 
 7 public class UserServiceImpl implements UserService {
 8 
 9     private UserDao userDao;
10 
11     public UserDao getUserDao() {
12         return userDao;
13     }
14 
15     public void setUserDao(UserDao userDao) {
16         this.userDao = userDao;
17     }
18 
19     @Override
20     public User login(String name, String pass) {
21         User user = userDao.findById(name);
22         if (user.getLoginPass().equals(pass)) {
23             return user;
24         }
25         return null;
26     }
27 }


8.spring配置文件
a.后置增强 -- applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 9 
10     <!-- 使用IoC完成依赖注入 -->
11     <bean id="userDao" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserDaoImpl"></bean>
12 
13     <bean id="userService" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserServiceImpl">
14         <property name="userDao" ref="userDao"></property>
15     </bean>
16     
17     <!-- 织入切面(方法执行前的操作) -->
18     <bean id="loggerBefore" class="com.Elastic.SpringDemo2.ivy.aop.LoggerBefore"></bean>
19     
20     <!-- 使用切面 -->
21     <aop:config>
22         <!-- <aop:pointcut expression="execution(public com.Elastic.SpringDemo2.ivy.entity.User login(java.lang.String, java.lang.String))" id="pointcut"/> -->
23         <aop:pointcut expression="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))" id="pointcut"/>
24         <aop:advisor advice-ref="loggerBefore" pointcut-ref="pointcut"/>
25     </aop:config>
26     
27 </beans>


b.后置增强 -- applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 9 
10     <!-- 使用IoC完成依赖注入 -->
11     <bean id="userDao" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserDaoImpl"></bean>
12 
13     <bean id="userService" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserServiceImpl">
14         <property name="userDao" ref="userDao"></property>
15     </bean>
16     
17     <!-- 织入切面(方法执行前的操作) -->
18     <bean id="loggerBefore" class="com.Elastic.SpringDemo2.ivy.aop.LoggerBefore"></bean>
19     <bean id="loggerAfter" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAfter"></bean>
20     
21     <!-- 使用切面 -->
22     <aop:config>
23         <!-- <aop:pointcut expression="execution(public com.Elastic.SpringDemo2.ivy.entity.User login(java.lang.String, java.lang.String))" id="pointcut"/> -->
24         <aop:pointcut expression="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))" id="pointcut"/>
25         <aop:advisor advice-ref="loggerBefore" pointcut-ref="pointcut"/>
26         
27         <aop:advisor advice-ref="loggerAfter" pointcut-ref="pointcut"/>
28     </aop:config>
29     
30 </beans>


c.异常抛出增强 -- applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 9 
10     <!-- 使用IoC完成依赖注入 -->
11     <bean id="userDao" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserDaoImpl"></bean>
12 
13     <bean id="userService" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserServiceImpl">
14         <property name="userDao" ref="userDao"></property>
15     </bean>
16     
17     <!-- 织入切面(方法执行前的操作) -->
18     <bean id="loggerBefore" class="com.Elastic.SpringDemo2.ivy.aop.LoggerBefore"></bean>
19     <bean id="loggerAfter" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAfter"></bean>
20     <bean id="loggerException" class="com.Elastic.SpringDemo2.ivy.aop.LoggerException" ></bean>
21     
22     
23     <!-- 使用切面 -->
24     <aop:config>
25         <!-- <aop:pointcut expression="execution(public com.Elastic.SpringDemo2.ivy.entity.User login(java.lang.String, java.lang.String))" id="pointcut"/> -->
26         <aop:pointcut expression="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))" id="pointcut"/>
27         <aop:advisor advice-ref="loggerBefore" pointcut-ref="pointcut"/>
28         <aop:advisor advice-ref="loggerAfter" pointcut-ref="pointcut"/>
29         <aop:advisor advice-ref="loggerException" pointcut-ref="pointcut"/>
30     </aop:config>
31     
32 </beans>


d.环绕增强 -- applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 9 
10     <!-- 使用IoC完成依赖注入 -->
11     <bean id="userDao" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserDaoImpl"></bean>
12 
13     <bean id="userService" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserServiceImpl">
14         <property name="userDao" ref="userDao"></property>
15     </bean>
16     
17     <!-- 织入切面(方法执行前的操作) -->
18     <bean id="loggerBefore" class="com.Elastic.SpringDemo2.ivy.aop.LoggerBefore"></bean>
19     <bean id="loggerAfter" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAfter"></bean>
20     <bean id="loggerException" class="com.Elastic.SpringDemo2.ivy.aop.LoggerException" ></bean>
21     <bean id="loggerArround" class="com.Elastic.SpringDemo2.ivy.aop.LoggerArround" ></bean>
22     
23     
24     <!-- 使用切面 -->
25     <aop:config>
26         <!-- <aop:pointcut expression="execution(public com.Elastic.SpringDemo2.ivy.entity.User login(java.lang.String, java.lang.String))" id="pointcut"/> -->
27         <aop:pointcut expression="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))" id="pointcut"/>
28         <!-- 环绕增强有顺序 -->
29         <aop:advisor advice-ref="loggerArround" pointcut-ref="pointcut"/>
30         <aop:advisor advice-ref="loggerBefore" pointcut-ref="pointcut"/>
31         <aop:advisor advice-ref="loggerAfter" pointcut-ref="pointcut"/>
32         <aop:advisor advice-ref="loggerException" pointcut-ref="pointcut"/>
33         
34     </aop:config>
35     
36 </beans>


e.使用注解 -- applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 9 
10     <!-- 使用IoC完成依赖注入 -->
11     <bean id="userDao" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserDaoImpl"></bean>
12 
13     <bean id="userService" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserServiceImpl">
14         <property name="userDao" ref="userDao"></property>
15     </bean>
16     
17     <!-- 织入切面(方法执行前的操作) -->
18     <bean id="loggerBefore" class="com.Elastic.SpringDemo2.ivy.aop.LoggerBefore"></bean>
19     <bean id="loggerAfter" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAfter"></bean>
20     <bean id="loggerException" class="com.Elastic.SpringDemo2.ivy.aop.LoggerException" ></bean>
21     <bean id="loggerArround" class="com.Elastic.SpringDemo2.ivy.aop.LoggerArround" ></bean>
22     
23     <!-- 使用注解 -->
24     <bean id="loggerAop" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAOP"></bean>
25     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
26     
27 </beans>


f.使用schema -- applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
 9 
10     <!-- 使用IoC完成依赖注入 -->
11     <bean id="userDao" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserDaoImpl"></bean>
12 
13     <bean id="userService" class="com.Elastic.SpringDemo2.ivy.dao.impl.UserServiceImpl">
14         <property name="userDao" ref="userDao"></property>
15     </bean>
16     
17     <!-- 织入切面(方法执行前的操作) -->
18     <bean id="loggerBefore" class="com.Elastic.SpringDemo2.ivy.aop.LoggerBefore"></bean>
19     <bean id="loggerAfter" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAfter"></bean>
20     <bean id="loggerException" class="com.Elastic.SpringDemo2.ivy.aop.LoggerException" ></bean>
21     <bean id="loggerArround" class="com.Elastic.SpringDemo2.ivy.aop.LoggerArround" ></bean>
22     
23     
24     <!-- 使用切面 -->
25     <aop:config>
26         <!-- 使用schema -->
27         <aop:aspect ref="loggerAop">
28             <aop:pointcut expression="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))" id="pointcut"/>
29             <aop:before method="before" pointcut-ref="pointcut"/>
30             <aop:after-returning method="after" pointcut-ref="pointcut" returning="returnValue"/>
31         </aop:aspect>
32     </aop:config>
33     
34     <!-- 使用注解 -->
35     <bean id="loggerAop" class="com.Elastic.SpringDemo2.ivy.aop.LoggerAOP"></bean>
36     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
37     
38 </beans>


9.aop包
a.前置增强 -- LoggerBefore类

 1 package com.Elastic.SpringDemo2.ivy.aop;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.springframework.aop.MethodBeforeAdvice;
 6 
 7 public class LoggerBefore implements MethodBeforeAdvice{
 8 
 9     @Override
10     public void before(Method method, Object[] arg, Object target)
11             throws Throwable {
12         System.out.println("执行" + method.getName() + "之前:......");
13     }
14 }


b.后置增强

 1 package com.Elastic.SpringDemo2.ivy.aop;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.springframework.aop.AfterReturningAdvice;
 6 
 7 public class LoggerAfter implements AfterReturningAdvice{
 8 
 9     @Override
10     public void afterReturning(Object returnValue, Method method, Object[] args,
11             Object target) throws Throwable {
12         System.out.println("方法返回值是:" + returnValue);
13         
14     }
15 }


c.异常抛出增强

 1 package com.Elastic.SpringDemo2.ivy.aop;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.springframework.aop.ThrowsAdvice;
 6 
 7 public class LoggerException implements ThrowsAdvice {
 8     public void afterThrowing(Method method, Object[] args, Object target, Throwable e) {
 9         System.out.println("方法" + method.getName() + "调用时出现异常");
10     }
11 }


d.环绕增强

 1 package com.Elastic.SpringDemo2.ivy.aop;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.aopalliance.intercept.MethodInterceptor;
 6 import org.aopalliance.intercept.MethodInvocation;
 7 
 8 public class LoggerArround implements MethodInterceptor{
 9 
10     @Override
11     public Object invoke(MethodInvocation invocation) throws Throwable {
12         System.out.println("方法执行前");
13         Object result = invocation.proceed();
14         System.out.println("方法执行后");
15         return result;
16     }
17 }


e.注解

 1 package com.Elastic.SpringDemo2.ivy.aop;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.annotation.AfterReturning;
 5 import org.aspectj.lang.annotation.Aspect;
 6 import org.aspectj.lang.annotation.Before;
 7 
 8 @Aspect(value="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))")
 9 public class LoggerAOP {
10     
11     //value 必填
12     @Before(value="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))")
13     public void before(JoinPoint point) {
14         System.out.println(point.getThis());
15         System.out.println(point.getArgs());
16         System.out.println(point.getTarget());
17 
18    //快照:副本
19         System.out.println(point.getSignature().getName());
20         System.out.println("使用注解完成方法执行之前的拦截");
21     }
22     
23     @AfterReturning(value="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))",returning="returnValue")
24     //returning的值与参数的值一样
25     public void after(JoinPoint point, Object returnValue) {
26         System.out.println("方法执行之后......");
27         System.out.println(point.getSignature());
28         System.out.println(returnValue);
29     }
30 }


f.schema

 1 package com.Elastic.SpringDemo2.ivy.aop;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.annotation.AfterReturning;
 5 import org.aspectj.lang.annotation.Aspect;
 6 import org.aspectj.lang.annotation.Before;
 7 
 8 //@Aspect(value="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))")
 9 public class LoggerAOP {
10     
11     //value 必填
12 //    @Before(value="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))")
13     public void before(JoinPoint point) {
14         System.out.println(point.getThis());
15         System.out.println(point.getArgs());
16         System.out.println(point.getTarget());
17         System.out.println(point.getSignature().getName());
18         System.out.println("使用注解完成方法执行之前的拦截");
19     }
20     
21 //    @AfterReturning(value="execution(* com.Elastic.SpringDemo2.ivy.service..*.*(..))",returning="returnValue")
22     //returning的值与参数的值一样
23     public void after(JoinPoint point, Object returnValue) {
24         System.out.println("方法执行之后......");
25         System.out.println(point.getSignature());
26         System.out.println(returnValue);
27     }
28 }


10.test包
a.前置增强 -- Test包

 1 package com.Elastic.SpringDemo2.ivy.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.Elastic.SpringDemo2.ivy.entity.User;
 7 import com.Elastic.SpringDemo2.ivy.service.UserService;
 8 
 9 public class Test {
10 
11     public static void main(String[] args) {
12         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
13         UserService userService = (UserService)context.getBean("userService");
14         User user = userService.login("admin", "123456");
15         if (null == user) {
16             System.out.println("登录失败");
17         } else {
18             System.out.println("登录成功");
19         }
20     }
21 }

b.异常抛出增强 -- Test类

 1 package com.Elastic.SpringDemo2.ivy.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.Elastic.SpringDemo2.ivy.entity.User;
 7 import com.Elastic.SpringDemo2.ivy.service.UserService;
 8 
 9 public class Test {
10 
11     public static void main(String[] args) {
12         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
13         UserService userService = (UserService)context.getBean("userService");
14         User user = userService.login("admin11111", "123456");
15         if (null == user) {
16             System.out.println("登录失败");
17         } else {
18             System.out.println("登录成功");
19         }
20     }
21 }

       
使用注解定义增强:
    1.AspectJ(静态代理)是一个面向切面的框架,它扩展了Java语言,定义了AOP 语法,能够在编译期提供代码的织入
    2.@AspectJ是AspectJ 5新增的功能,使用JDK 5.0 注解技术和正规的AspectJ切点表达式语言描述切面
    3.Spring通过集成AspectJ实现了以注解的方式定义增强类,大大减少了配置文件中的工作量
        a.使用@AspectJ,首先要保证所用的JDK 是5.0或以上版本
        b.将Spring的asm 模块添加到类路径中,以处理@AspectJ中所描述的方法参数名
    
    4.使用注解定义前置增强和后置增强实现日志功能
    5.常用注解有@Aspect、@Before、@AfterReturning、@Around、@AfterThrowing、@After等
    6.通过在配置文件中添加<aop:aspectj-autoproxy />元素,就可以启用对于@AspectJ注解的支持

    7.定义最终增强
        @AspectJ还提供了一种最终增强类型,无论方法抛出异常还是正常退出,该增强都会得到执行,类似于异常处理机制中finally块的作用,一般用于释放资源

使用Schema配置切面    
    POJO的方法配置成切面,所用标签包括<aop:aspect>、<aop:before>、<aop:after-returning>、<aop:around>、<aop:after-throwing>、<aop:after>等

Spring AOP and AspectJ AOP 有什么区别?

  • AspectJ 静态代理(AOP框架在编译期生成AOP代理类)。在编译阶段将AspectJ(切面)织入到java字节码中,运行时就是增强的AOP对象。
  • Spring AOP 动态代理。AOP框架不会修改字节码,每次运行时在内存中临时生成一个AOP对象,这个AOP对象包含目标对象的全部方法,在特定的切点做了增强处理,并回调原对象方法。
原文地址:https://www.cnblogs.com/ivy-xu/p/5645540.html