Spring的AOP开发xml方式

Spring的AOP开发(AspectJ的xml方式)

Spring的AOP简介

AOP思想最早是由AOP联盟组织提出的,Spring是使用这种思想的最好框架

        Spring的AOP有自己的实现方式(非常繁琐)。AspectJ是一个AOP框架,Spring引入AspectJ作为自身AOP的开发

        Spring的两套AOP开发方式

                  Spring传统方式(弃用)

                  Spring基于AspectJ的AOP的开发(使用)

AOP中的相关术语

 Spring的AOP入门(基于AspectJ的xml方式)

创建web项目,引入jar包

除了原来的核心包和日志包外还需要下面四个

创建配置文件

引入约束

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
</beans>

编写目标类并完成配置

实现了接口的目标类

/**
 * 接口
 * @author ysh
 * ProductDao.java
 * 2018年11月1日  下午2:14:44
 */
public interface ProductDao {
	public void save();
	public void delete();
	public void update();
	public void find();
}
/**
 * 实现类
 * @author ysh
 * ProductDaoImp.java
 * 2018年11月1日  下午2:15:21
 *
 */
public class ProductDaoImp implements ProductDao{
	@Override
	public void save() {
		System.out.println("saving products ....");
	}
	@Override
	public void delete() {
		System.out.println("deleting products ....");
	}
	@Override
	public void update() {
		System.out.println("updating products ....");
	}
	@Override
	public void find() {
		System.out.println("finding products ....");
	}
}
<bean id="productDao" class="/springAOP/src/com/bwf/train1/ProductDaoImp"></bean>

编写测试类

Spring整合Junit(之后的测试都是用的本类中的方法,不用改动

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
	
	/*@Test
	public void train1() {
		//通过工厂获取bean
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		ProductDao dao = (ProductDao) applicationContext.getBean("productDao");
		dao.save();
		dao.delete();
		dao.update();
		dao.find();
	}
	*/
	/*每次都要调用工厂方法,很麻烦,Spring提供了一种与Junit整合的办法(有一个jar包,框架包中的test包),
	可以通过在类上注解省去这一步骤*/
	@Resource(name="productDao")
	private ProductDao productDao;
	
	@Test
	public void train2() {
		productDao.save();
		productDao.delete();
		productDao.update();
		productDao.find();
		
	}

}

接下来,对save方法进行加强

配置切面

编写一个切面类

public class AspectXML {
	public void checkPri() {
		System.out.println("checked the user authority...");
	}
}

将切面类交个spring管理

<!-- 将切面类交个Spring管理 -->
        <bean id="AspectXMl" class="com.bwf.train1.AspectXML"></bean>

配置切面

 测试结果

Spring中通知的类型

AspectJ中根据执行的先后顺序,将通知分为以下几类

前置通知    

在目标方法执行之前进行操作   配置文件中用  aop:before  标签

前置通知   获取切入点信息

//在切面类中的方法中设置一个JoinPoint对象,可以输出JoinPoint(切入点)信息
public class AspectXML {
	public void checkPri(Joinpoint joinPoint) {
		System.out.println("checked the user authority..."+joinPoint);
	}
}

 运行结果

后置通知    

在目标方法执行之后进行操作    配置文件中用  aop:after-returning  标签

后置通知    可以获取返回值

给delete方法改为返回一个String值

对delete方法进行后置通知,要获取返回值,需要设置一个returning属性

 

测试结果

环绕通知    

在目标方法执行之前和之后进行操作    (添加事务可以用环绕通知)配置文件中用  aop:around  标签

环绕通知    阻止目标方法的执行(通知不执行,目标方法就没办法执行)

给update方法进行性能的监控

/**
	 * 环绕通知    性能监控
	 * 必须返回Object类型,设置一个
	 * @throws Throwable 
	 */
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("环绕前=====");
		//这里相当于执行目标方法,目标方法可能有返回值,所以要返回一个object类型值
		Object proceed = joinPoint.proceed();
		System.out.println("环绕后=====");
		return proceed;
	}

 

测试结果 

异常抛出通知    

在程序出现异常时进行操作(在事物管理的时候,提交事物时,出现异常,回滚)

对find方法进行异常抛出通知

/**
	 * 异常抛出通知
	 */
	public void afterThrow() {
		System.out.println("异常抛出了。。。。");
	}

测试结果

 

异常抛出通知   可以获取异常信息,只需要在切面配置中设置一个throwing属性 

 

 在通知方法中做如下改动

测试结果

最终通知    

不管代码是否有异常,总是会执行(相当于try...catch....finally中的finally中的内容)

对find进行最终通知操作

/**
	 * 最终通知   不管异常抛不抛出,都会执行
	 */
	public void after() {
		System.out.println("最终执行的操作");
	}

 测试结果

引介通知(不会用到)

Spring切入点表达式的写法

切入点表达式语法:

基于execution()的函数来完成的

语法    [ ]表示可选   

      [ 访问修饰符 ] 空格 方法的返回值 空格 包名.类名.方法名(参数)

例如  public void com.bwf.spring.CustomerDao.save(..)

         *  *.*.*Dao.save(..)表示返回值是任意类型,有两层包名,类名以Dao结束的有任意参数的save方法,即所有dao中的save方法都可以被增强

         * com.bwf.spring.CustomerDao+.save(..)  " + "表示CustomerDao类和其子类

          * com.bwf.spring..*.*(..)   表示com.bwf.spring这个包及其子包下的所有类的所有方法

           * *.*.*(..)  表示所有包下的所有类中的所有方法

猜你喜欢

转载自blog.csdn.net/bright_light12345/article/details/83618918