AspectJ

 

1.1 介绍

AspectJ是一个基于Java语言的AOP框架

Spring2.0以后新增了对AspectJ切点表达式支持

@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面

新版本Spring框架,建议使用AspectJ方式来开发AOP

主要用途:自定义开发

 

1.2 切入点表达式【掌握】

1.execution()  用于描述方法 【掌握】

语法:execution(修饰符  返回值  包.类.方法名(参数) throws异常)

修饰符,一般省略

public 公共方法

* 任意

返回值,不能省略

void 返回没有值

String 返回值字符串

* 任意

包,[省略]

com.itheima.crm 固定包

com.itheima.crm.*.service crm包下面子包任意 (例如:com.itheima.crm.staff.service)

com.itheima.crm.. crm包下面的所有子包(含自己)

com.itheima.crm.*.service.. crm包下面任意子包,固定目录service,service目录任意包

类,[省略]

UserServiceImpl   指定类

*Impl             以Impl结尾

User*             以User开头

*                     任意

方法名,不能省略

addUser                固定方法

add*                     以add开头

*Do                      以Do结尾

* 任意

(参数)

() 无参

(int)              一个整型

(int ,int)        两个

(..)                  参数任意

throws ,可省略,一般不写。

 

综合1

execution(* com.itheima.crm.*.service..*.*(..))

综合2

<aop:pointcut expression="execution(* com.itheima.*WithCommit.*(..)) ||

                          execution(* com.itheima.*Service.*(..))" id="myPointCut"/>

2.within:匹配包或子包中的方法(了解)

within(com.itheima.aop..*)

3.this:匹配实现接口的代理对象中的方法(了解)

this(com.itheima.aop.user.UserDAO)

4.target:匹配实现接口的目标对象中的方法(了解)

target(com.itheima.aop.user.UserDAO)

5.args:匹配参数格式符合标准的方法(了解)

args(int,int)

6.bean(id)  对指定的bean所有的方法(了解)

bean('userServiceId')

 

1.3 AspectJ 通知类型

l aop联盟定义通知类型,具有特性接口,必须实现,从而确定方法名称。

l aspectj 通知类型,只定义类型名称。已经方法格式。

l 个数:6种,知道5种,掌握1中。

before:前置通知(应用:各种校验)

在方法执行前执行,如果通知抛出异常,阻止方法运行

afterReturning:后置通知(应用:常规数据处理)

方法正常返回后执行,如果方法中抛出异常,通知无法执行

必须在方法执行后才执行,所以可以获得方法的返回值。

around:环绕通知(应用:十分强大,可以做任何事情)

方法执行前后分别执行,可以阻止方法的执行

必须手动执行目标方法

afterThrowing:抛出异常通知(应用:包装异常信息)

方法抛出异常后执行,如果方法没有抛出异常,无法执行

after:最终通知(应用:清理现场)

方法执行完毕后执行,无论方法中是否出现异常

环绕

 

try{

     //前置:before

    //手动执行目标方法

    //后置:afterRetruning

} catch(){

    //抛出异常 afterThrowing

} finally{

    //最终 after

}


1.4 导入jar包

l 4个:

aop联盟规范

spring aop 实现

aspect 规范

spring aspect 实现

 

1.5 基于xml

1.目标类:接口 + 实现

2.切面类:编写多个通知,采用aspectj 通知名称任意(方法名任意)

3.aop编程,将通知应用到目标类

4.测试

1.5.1 切面类

 

	
	
	public void myBefore(JoinPoint joinPoint){
		
		System.out.println("前置通知:"+joinPoint.getSignature().getName());
	}
	
	public void myAfterReturning(JoinPoint joinPoint,Object obj){
		  
		System.out.println("后置通知:"+joinPoint.getSignature().getName()+",--->>"+obj);
		
	}
	
	
	public Object myAround(ProceedingJoinPoint  joinPoint) throws Throwable{
		  
		System.out.println("前");
		//手动执行目标方法
		Object obj = joinPoint.proceed();
		
		System.out.println("后");
		return obj;
	}
	
	public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
		System.out.println("抛出异常通知 : " + e.getMessage());
	}
	
	public void myAfter(JoinPoint joinPoint){
		System.out.println("最终通知");
	}

}

1.5.2 ApplicationContext配置

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

	<!-- 自动扫描 --> 
    <context:component-scan base-package="com.bsoft.cn" /> 
    <!-- 引入配置文件 --> 
    <bean id="propertyConfigurer" 
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
        <property name="location" value="classpath:jdbc.properties" /> 
    </bean> 
   
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
        destroy-method="close"> 
        <property name="driverClassName" value="${driver}" /> 
        <property name="url" value="${url}" /> 
        <property name="username" value="${username}" /> 
        <property name="password" value="${password}" /> 
        <!-- 初始化连接大小 --> 
        <property name="initialSize" value="${initialSize}"></property> 
        <!-- 连接池最大数量 --> 
        <property name="maxActive" value="${maxActive}"></property> 
        <!-- 连接池最大空闲 --> 
        <property name="maxIdle" value="${maxIdle}"></property> 
        <!-- 连接池最小空闲 --> 
        <property name="minIdle" value="${minIdle}"></property> 
        <!-- 获取连接最大等待时间 --> 
        <property name="maxWait" value="${maxWait}"></property> 
    </bean> 
   
    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --> 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
        <property name="dataSource" ref="dataSource" /> 
        <property name="configLocation" value="classpath:mybatisConfig.xml" />
        <!-- 自动扫描mapping.xml文件 --> 
        <property name="mapperLocations" value="classpath:com/bsoft/cn/**/dao/mapping/*.xml"></property> 
    </bean> 
   
    <!-- DAO接口所在包名,Spring会自动查找其下的类 --> 
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
        <property name="basePackage" value="com.bsoft.cn.test.dao" /> 
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> 
    </bean> 
   
    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> 
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
        <property name="dataSource" ref="dataSource" /> 
    </bean> 
    <bean id="quartzTestTask" class="com.bsoft.cn.test.task.TestTask"/>
    <!-- quartz配置 -->
    <!-- 定义调用对象和调用对象的方法 -->
	<bean id="quartzTestBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<!--调用的类 -->
		<property name="targetObject" ref="quartzTestTask" />
		<!--调用类中的方法 -->
		<property name="targetMethod" value="test" />
	</bean>
	
	<!-- 定义触发时间 -->
	<bean id="testCronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail" ref="quartzTestBean" />
		 <!--cron表达式 -->
		<property name="cronExpression" value="0 0/1 * * * ?"/>
	</bean>
	
	<!--任务总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序  -->
	<bean id="schedulerFactoryBean" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
      			<ref bean="testCronTriggerBean"/>
			</list>
		</property>
	</bean>
	<!-- satart -->
    <!-- 1 创建目标类 -->
	<bean id="userServiceId" class="com.bsoft.cn.spring_aspect.a_xml.UserServiceImpl"/> 
	<!-- 2 创建切面类(通知) -->
	<bean id="myAspectId" class="com.bsoft.cn.spring_aspect.a_xml.MyAspect"/>
	<!-- 3.aop编程 -->
	<aop:config>
	   <aop:aspect ref="myAspectId">
	      <aop:pointcut expression="execution(* com.bsoft.cn.spring_aspect.a_xml.UserServiceImpl.*(..))" id="myPointCut"/>
	       <!-- 3.1 前置通知 
				<aop:before method="" pointcut="" pointcut-ref=""/>
					method : 通知,及方法名
					pointcut :切入点表达式,此表达式只能当前通知使用。
					pointcut-ref : 切入点引用,可以与其他通知共享切入点。
				通知方法格式:public void myBefore(JoinPoint joinPoint){
					参数1:org.aspectj.lang.JoinPoint  用于描述连接点(目标方法),获得目标方法名等
				例如:
		 
		 <aop:before method="myBefore" pointcut-ref="myPointCut"/>
		-->
		
		<!-- 3.2后置通知  ,目标方法后执行,获得返回值
				<aop:after-returning method="" pointcut-ref="" returning=""/>
					returning 通知方法第二个参数的名称
				通知方法格式:public void myAfterReturning(JoinPoint joinPoint,Object ret){
					参数1:连接点描述
					参数2:类型Object,参数名 returning="ret" 配置的
				例如:
			<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="obj" />
			-->
			
			<!-- 3.3 环绕通知 
				<aop:around method="" pointcut-ref=""/>
				通知方法格式:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
					返回值类型:Object
					方法名:任意
					参数:org.aspectj.lang.ProceedingJoinPoint
					抛出异常
				执行目标方法:Object obj = joinPoint.proceed();
				例如:
		
				<aop:around method="myAround" pointcut-ref="myPointCut"/>
			-->
			<!-- 3.4 抛出异常
				<aop:after-throwing method="" pointcut-ref="" throwing=""/>
					throwing :通知方法的第二个参数名称
				通知方法格式:public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
					参数1:连接点描述对象
					参数2:获得异常信息,类型Throwable ,参数名由throwing="e" 配置
				例如:
			<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>
			-->
			<!-- 3.5 最终通知 -->			
			<aop:after method="myAfter" pointcut-ref="myPointCut"/>
		    
	   </aop:aspect>
	</aop:config>
	<!-- end -->
	
	
</beans>

 

有兴趣的朋友可以关注下本人的微信公众号:“JAVA菜鸟程序猿”

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA菜鸟程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值