在说使用AOP面向切面编程的思想对代码段进行增强处理之前,先说两个理论知识点:
—常用切入表达式模糊匹配解释:
①public * addUser(com.pb.entity.User): “*”表示匹配所有类型的返回值;
②public void * (com.pb.eneity.User): “*”表示匹配所有方法名;
③public void addUser(..): “…”表示匹配所有参数个数和类型;
④* com.pb.service.* . *(..):匹配com.pb.service包下所有类的所有方法;
⑤* cpm.pb.service..*( ):匹配cpm.pb.service包及子包下所有类的所有方法。
使用的时候可以根据需求来设置切入点的匹配规则。
—增强处理类型:
①Before:前置增强处理,在目标方法前织入;
②AfterReturning:后置增强处理,在目标方法正常执行后织入;
③AfterThrowing:异常增强处理,在目标方法抛出异常后织入;
④After:最终增强处理,不论方法是否抛出异常,都会在目标方法最后织入;
⑤Around:环绕增强处理,在目标方法的前后都可以织入增强处理。
案例:
1.首先有一个User的实体类,拥有以下几个属性:
private Integer id; // 用户ID
private String username; // 用户名
private String password; // 密码private String email; // 电子邮件 . //get和set方法省略2.编写bean四层代码,除了daoImpl代码与之前有所区别,其他都一样:
dao:
/** * 增加DAO接口,定义了所需的持久化方法 */
daoImpl:public interface IDao { public void save(User user);}
/** * 用户DAO类,实现IDao接口,负责User类的持久化操作 */
public class UserDao implements IDao { public void save(User user) { // 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");throw new RuntimeException("为测试程序运行效果抛出的异常");//throw new SQLException("为测试程序运行效果抛出的异常"); }}biz:
/** * 用户业务接口,定义了所需的业务方法 */
bizImpl:public interface IUserBiz { public void addNewUser(User user);}
/** * 用户业务类,实现对User功能的业务管理 */
public class UserBiz implements IUserBiz { // 声明接口类型的引用,和具体实现类解耦合
private IDao dao; // dao 属性的setter访问器,会被Spring调用,实现设值注入public void setDao(IDao dao) { this.dao = dao; }public void addNewUser(User user) { // 调用用户DAO的方法保存用户信息dao.save(user); }}在数据访问层,我人为的抛出了一个异常,用于测试异常的织入是否正常。那么接下来,就来创建织入的程序类:3.ErrorLogger 类:
/** * 通过ThrowsAdvice接口实现异常抛出增强 */
public class ErrorLogger implements ThrowsAdvice {
private static final Logger log = Logger.getLogger(ErrorLogger.class);public void afterThrowing(Method method, Object[] args, Object target,RuntimeException e) {log.error(method.getName() + " 方法发生异常:" + e); }public void afterThrowing(Method method, Object[] args, Object target,SQLException ex) {log.error(method.getName() + " 方法发生异常:" + ex); }}4.配置文件:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<!-- ↓↓引入aop相关命名空间↓↓ -->xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.1.xsd<!-- ↓↓引入aop相关命名空间↓↓ -->http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.1.xsd"><bean id="dao" class="dao.impl.UserDao"></bean><bean id="biz" class="biz.impl.UserBiz"><property name="dao" ref="dao"></property></bean><!-- ↓↓定义增强组件↓↓ --><bean id="errorLogger" class="aop.ErrorLogger"></bean><aop:config><!-- ↓↓指定增强处理的范围 ↓↓ --><aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" /><!-- ↓↓引用,装配组件↓↓ --><aop:advisor pointcut-ref="pointcut" advice-ref="errorLogger" /></aop:config></beans>5.最后,来编写一个测试类Test,触发异常增强,看看效果:
public class Test { /** * @param args */ public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserBiz biz = (IUserBiz) ctx.getBean("biz");User user = new User();user.setId(1);user.setUsername("test");user.setPassword("123456");user.setEmail("test@pbdevj.com");biz.addNewUser(user); }}6.执行后效果:
程序准确的捕捉到了异常并抛出。