本文章主要介绍了JavaWeb学习-Spring框架-11-Spring aop开发-导包和定义通知和配置织入对象,具有不错的的参考价值,希望对您有所帮助,如解说有误或未考虑完全的地方,请您留言指出,谢谢!

在开始AOP编程之前,我们前面介绍了几个aop名词,很生涩,不好理解,没办法,我们只能从实际操作去理解和体会每一个名词对应的动作。本篇练习的具体步骤

1.导入包 
 
2.准备目标对象 
 
3.准备通知 
 
4.配置进行织入,将通知织入目标对象

1.导入包

com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-5.0.0.RELEASE.jar

如果这些部分包找不到,可以copy上面包名称去maven在线仓库搜索并下载。

2.准备目标对象

在src下新建一个com.anthony.service的包,然后创建一个接口和实现类。

package com.anthony.service; 
 
public interface UserService { 
	 
	/** 
	 * 保存用户信息 
	 */ 
	public void save(); 
	 
	/** 
	 * 删除用户 
	 */ 
	public void delete(); 
	 
	/** 
	 * 更新用户 
	 */ 
	public void update(); 
	 
	/** 
	 * 查找用户 
	 */ 
	public void find(); 
 
} 

具体实现类

package com.anthony.service; 
 
public class UserServiceImpl implements UserService { 
 
	@Override 
	public void save() { 
		System.out.println("保存用户"); 
	} 
 
	@Override 
	public void delete() { 
		System.out.println("删除用户"); 
	} 
 
	@Override 
	public void update() { 
		System.out.println("更新用户"); 
	} 
 
	@Override 
	public void find() { 
		System.out.println("查找用户"); 
	} 
 
} 

对象准备好了,下面来定义通知。

3.准备通知

新建com.anthony.springaop包,并写一个MyAdvice类作为通知类。

package com.anthony.springaop; 
 
import org.aspectj.lang.ProceedingJoinPoint; 
 
//前置通知 
	//目标方法运行之前调用 
//后置通知(如果出现异常不会调用) 
	//在目标方法运行之前调用 
//环绕通知 
	//在目标方法之前和之后都调用 
//异常拦截通知 
	//如果出现异常。就会调用 
//后置通知(无论是否出现异常都会调用) 
	//在目标方法运行之后调用 
 
public class MyAdvice { 
	 
	//前置通知 
	public void before() { 
		System.out.println("这是前置通知!"); 
	} 
	 
	//前置通知 
	public void afterReturning() { 
		System.out.println("这是后置通知!如果出现异常不会调用"); 
	} 
	 
	//环绕通知 
	public Object around(ProceedingJoinPoint pjp) throws Throwable { 
		System.out.println("这是环绕通知之前部分"); 
		Object proceed = pjp.proceed(); 
		System.out.println("这是环绕通知之后"); 
		return proceed; 
	} 
	 
	//异常拦截通知 
	public void afterException() { 
		System.out.println("出现异常了!"); 
	} 
	 
	//后置通知 
	public void after() { 
		System.out.println("这是后置通知!无论是否出现异常也会调用"); 
	} 
	 
} 

4.配置进行织入,将通知织入目标对象

还是在springaop包,然后把之前src目录下的applicationContext.xml复制一份到springaop包下,接下来需要导入aop约束。

<?xml version="1.0" encoding="UTF-8"?> 
 
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
	   xmlns="http://www.springframework.org/schema/beans"  
	   xmlns:context="http://www.springframework.org/schema/context"  
	   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/context  
	   http://www.springframework.org/schema/context/spring-context.xsd  
	   http://www.springframework.org/schema/aop  
	   http://www.springframework.org/schema/aop/spring-aop.xsd "> 
 
 
 
 
</beans> 

4.1 配置切入点

下面是一个配置切入点配置

<?xml version="1.0" encoding="UTF-8"?> 
 
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
	   xmlns="http://www.springframework.org/schema/beans"  
	   xmlns:context="http://www.springframework.org/schema/context"  
	   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/context  
	   http://www.springframework.org/schema/context/spring-context.xsd  
	   http://www.springframework.org/schema/aop  
	   http://www.springframework.org/schema/aop/spring-aop.xsd "> 
 
 
	<!-- 1 配置目标对象 --> 
	<bean name="userServiceTarget" class="com.anthony.service.UserServiceImpl"></bean> 
	<!-- 2 配置通知对象 --> 
	<bean name="myAdvice" class="com.anthony.springaop.MyAdvice"></bean> 
	<!-- 3 配置通知织入目标对象 --> 
	<aop:config> 
		<!-- 配置切入点 --> 
		<!-- 下面这行表示,只给目标对象中的save方法进行增强 --> 
		<aop:pointcut expression="execution(public void com.anthony.service.UserServiceImpl.save())" id="pc"/> 
		<aop:aspect></aop:aspect> 
		 
	</aop:config> 
</beans> 

关于配置切入点增强方法的写法 “public void com.anthony.service.UserServiceImpl.save()”的解释和演变过程

public void com.anthony.service.UserServiceImpl.save() 
这个我们例子中写法,很规矩的写法 
 
演变1: 
void com.anthony.service.UserServiceImpl.save() 
因为默认是public,也只能是public修饰,这里public可以省去 
 
演变2: 
 * com.anthony.service.UserServiceImpl.save() 
切入点支持任何返回类型,上面这个*表示任何返回类型 
 
演变3: 
* com.anthony.service.UserServiceImpl.*() 
这个表示对某一个包下类的全部方法进行增强,只对于空参方法 
 
演变4: 
* com.anthony.service.*ServiceImpl.*(..) 
意思是找service包下所以带ServiceImpl类下的所有方法给增强 
这种写法是以后开发中常见的写法。

完整的通知织入对象配置如下

<?xml version="1.0" encoding="UTF-8"?> 
 
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
	   xmlns="http://www.springframework.org/schema/beans"  
	   xmlns:context="http://www.springframework.org/schema/context"  
	   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/context  
	   http://www.springframework.org/schema/context/spring-context.xsd  
	   http://www.springframework.org/schema/aop  
	   http://www.springframework.org/schema/aop/spring-aop.xsd "> 
 
 
	<!-- 1 配置目标对象 --> 
	<bean name="userServiceTarget" class="com.anthony.service.UserServiceImpl"></bean> 
	<!-- 2 配置通知对象 --> 
	<bean name="myAdvice" class="com.anthony.springaop.MyAdvice"></bean> 
	<!-- 3 配置通知织入目标对象 --> 
	<aop:config> 
		<!-- 配置切入点 --> 
		<!-- 下面这行表示,只给目标对象中的save方法进行增强 --> 
		<aop:pointcut expression="execution(public void com.anthony.service.UserServiceImpl.save())" id="pc"/> 
		<aop:aspect ref="myAdvice"> 
			<!-- 指定 名为before方法为前置通知--> 
			<aop:before method="before" pointcut-ref="pc" /> 
			<!-- 后置通知 --> 
			<aop:after-returning method="afterReturning" pointcut-ref="pc" /> 
			<!-- 环绕通知 --> 
			<aop:around method="around" pointcut-ref="pc" /> 
			<!-- 异常通知 --> 
			<aop:after-throwing method="afterException" pointcut-ref="pc"/> 
			<!-- 后置通知 --> 
			<aop:after method="after" pointcut-ref="pc"/> 
		</aop:aspect> 
		 
	</aop:config> 
</beans> 

5.测试

把之前的Demo1.java测试类拷贝一份到springaop包下,修改代码如下

package com.anthony.springaop; 
  
import javax.annotation.Resource; 
 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
 
import com.anthony.service.UserService; 
 
// 帮我们创建容器 
@RunWith(SpringJUnit4ClassRunner.class) 
// 指定创建容器时使用哪一个配置文件 
@ContextConfiguration("classpath:com/anthony/springaop/applicationContext.xml") 
public class Demo1 { 
	 
	@Resource(name="userServiceTarget") 
	private UserService us; 
	 
	@Test 
	public void fun1() { 
		us.save(); 
	} 
  
}

运行Jnuit测试

这是前置通知! 
这是环绕通知之前部分 
保存用户 
这是后置通知!无论是否出现异常也会调用 
这是环绕通知之后 
这是后置通知!如果出现异常不会调用

其实,到了这里,aop的思想都学习完了,只是我们缺少实际项目练习并去体会这种思想。下一篇,我要回到java web学习,继续学习之前java web没有完成的课程,spring框架后面再来学习。Spring框架后面的学习主要是和JDBC集成,和Mybatis框架集成,SSH集成就不学习,这两东西现在基本都不用了。


发布评论
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

JavaWeb学习-案例练习-图书管理后台-1- 环境搭建详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。