在说使用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接口,定义了所需的持久化方法 */
public interface IDao { public void save(User user);}
daoImpl:
/** * 用户DAO类,实现IDao接口,负责User类的持久化操作 */
public class UserDao implements IDao { public void save(User user) { // 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");
throw new RuntimeException("为测试程序运行效果抛出的异常");
//throw new SQLException("为测试程序运行效果抛出的异常"); }}
biz:
/** * 用户业务接口,定义了所需的业务方法 */
public interface IUserBiz { public void addNewUser(User user);}
bizImpl:
/** * 用户业务类,实现对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/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
<!-- ↓↓引入aop相关命名空间↓↓ -->
http://www.springframework.org/schema/aop
http://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.执行后效果:
程序准确的捕捉到了异常并抛出。