Spring第三讲
内容:
1. spring切入点
2. advisor正则表达式
3. 自动代理
4. 使用aspect进行aop开发
5. 引入通知
6. 使用pojo+xml开发aop
7. Spring连接数据库
讲解:
1. spring切入点
定义切入点:如果不能表达在应用系统的什么地方应用
通知的话,通知将毫无用处,这就是切入点的用处。切入点决定了一个特定的类的特定方法是否满足一定的规则。若符合,通知就应用到该方法上, 如果1.返回true,2.被调用来决定MethodMatcher的类型。有两种类型:静态和动态。静态切入点的意思是通知总是被执行。如果一个切入点是静态的,该方法返回false.动态切入点根据运行时方法的参数值决定通知是否需要执行。如果切入点是动态的,该方法返回true。和1.方法类似,该方法也是在代理创建时运行一次。 如果切入点是静态的,3.永远不会执行,对于动态切入点,需要根据运行时的参数决定方法是否被通知,所以会增加系统的负担,尽量使用静态切入点。
使用Spring的静态切入点:
<bean id="nameMatchMethodPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
<property name="mappedNames">
<list>
<value>study</value>
</list>
</property>
<property name="advice">
<ref bean="myAroundAdvice"/>
</property>
</bean>
2. advisor正则表达式
<!-- 采用正则表达式 -->
<bean id="regexpMethodPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns">
<list>
<value>
.*tudy
</value>
</list>
</property>
<property name="advice">
<ref bean="myBeforeAdvice"/>
</property>
</bean><!-- 采用正则表达式 -->
<bean id="regexpMethodPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns">
<list>
<value>
.*tudy
</value>
</list>
</property>
<property name="advice">
<ref bean="myBeforeAdvice"/>
</property>
</bean>
3. 自动代理
<bean id="beanNameAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Bean</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>
myAroundAdvice
</value>
</list>
</property>
</bean>
4. 使用aspect进行aop开发
1> 添加类库:aspectjrt.jar和aspectjweaver.jar
2>添加aop schema.
3>定义xml元素:<aop:aspectj-autoproxy>
4>编写java类,并用@Aspect注解成通知
AspectJ 支持 5 种类型的通知注解:
@Before: 前置通知, 在方法执行之前执行
@After: 后置通知, 在方法执行之后执行
@AfterReturning: 返回通知, 在方法返回结果之后执行
@AfterThrowing: 异常通知, 在方法抛出异常之后
@Around: 环绕通知, 围绕着方法执行
5>配置成普通bean元素即可.
@Aspect
publicclass AspectUtil {
//简略写法
@Pointcut("execution(* *.work(..))")
publicvoid disp(){}
/**
* (* *.*(..)) // *包名+类名.*方法名
* (* *work(..)) //
* (public * *work(..)) public 修饰符 第一个*返回值类型 第二个*(包名+类名)work(..) //..参数任意
*/
@Before("disp()")
publicvoid getUp() {
System.out.println("...............该起床了........");
}
/**
* execution(* com.xyz.service.*.*(..))
* (* set*(..)) *返回值类型 (包名和类名) set方法名的开头*匹配所有
* (* cn.csdn.hr.service.EmployeeService.*(..))) 第一个*返回值 cn.csdn.hr.service.EmployeeService.*方法名(..参数任意)
* @throws Throwable
*/
@Around("disp()")
public Object punchCard(ProceedingJoinPoint jp) throws Throwable {
System.out.println(".............打卡................");
Object obj = jp.proceed();
System.out.println(".............打卡................");
return obj;
}
@AfterThrowing("disp()")
publicvoid unWell() {
System.out.println("...................需要请假...............");
}
@After("disp()")
publicvoid goHome() {
System.out.println(".............回家的路真漫长...............");
}
5. 引入通知
@Aspect
publicclass MyAspectAdive {
@DeclareParents(value="..")
private Auditable auditable;
}
6. 使用pojo+xml开发aop
优点:
基于注解的aspectj声明优先于xml配置.
基于xml的配置是spring专有的.aspectj得到越来越多的支持,
具备更好的重用性.
<!-- aop的配置 -->
<aop:config>
<!-- 声明切入点 -->
<aop:pointcut expression="execution(* *.work(..))" id="myPointcut"/>
<aop:pointcut expression="execution(* *.work(..)) and args(name,pass)" id="myPointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="adviceUtil">
<aop:before method="goHome" pointcut-ref="myPointcut"/>
<aop:before method="checkLogin" pointcut-ref="myPointcut1"/>
<aop:around method="punchCard" pointcut-ref="myPointcut"/>
<aop:after method="getUp" pointcut-ref="myPointcut"/>
<aop:after-returning method="back" pointcut-ref="myPointcut"/>
<aop:after-throwing method="unWell" pointcut-ref="myPointcut" throwing="ex"/>
<aop:declare-parents types-matching="*..EmployeeServiceBean"
implement-interface="cn.csdn.advice.Auditable" default-impl="cn.csdn.advice.AuditableAdvice"/>
</aop:aspect>
</aop:config>
7. Spring连接mysql数据库
1> 创建一个DataSource连接池
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>${driverClassName}</value>
</property>
<property name="url">
<value>${url}</value>
</property>
<property name="username">
<value>${username}</value>
</property>
<property name="password">
<value>${password}</value>
</property>
</bean>
<context:property-placeholder location="jdbc.properties" />
2> jdbcTemplate模板类和nameedparamterJdbcTemplate模板类
<!-- jdbcTemplate模板类 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- nameedparamterJdbcTemplate模板类 -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
3> 注入
<!-- 注入到Dao操作实现类中 -->
<bean id="adminDaoImpl" class="cn.csdn.dao.AdminsDaoImpl">
<!-- 注入模板类对象 -->
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="adminDaoNamedImpl" class="cn.csdn.dao.AdminDaoNamedImpl">
<!-- 注入模板类对象 -->
<property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"/>
</bean>