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的静态切入点:
<beanid="nameMatchMethodPointcutAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<propertyname="mappedNames">
<list>
<value>study</value>
</list>
</property>
<propertyname="advice">
<refbean="myAroundAdvice"/>
</property>
</bean>
2. advisor正则表达式
<!-- 采用正则表达式 -->
<bean id="regexpMethodPointcutAdvisor"class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<propertyname="patterns">
<list>
<value>
.*tudy
</value>
</list>
</property>
<propertyname="advice">
<refbean="myBeforeAdvice"/>
</property>
</bean><!--采用正则表达式 -->
<bean id="regexpMethodPointcutAdvisor"class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<propertyname="patterns">
<list>
<value>
.*tudy
</value>
</list>
</property>
<propertyname="advice">
<refbean="myBeforeAdvice"/>
</property>
</bean>
3. 自动代理
<beanid="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 Auditableauditable;
}
6. 使用pojo+xml开发aop
优点:
基于注解的aspectj声明优先于xml配置.
基于xml的配置是spring专有的.aspectj得到越来越多的支持,
具备更好的重用性.
<!--aop的配置 -->
<aop:config>
<!--声明切入点 -->
<aop:pointcutexpression="execution(* *.work(..))"id="myPointcut"/>
<aop:pointcutexpression="execution(* *.work(..)) and args(name,pass)"id="myPointcut1"/>
<!--配置切面 -->
<aop:aspectref="adviceUtil">
<aop:beforemethod="goHome"pointcut-ref="myPointcut"/>
<aop:beforemethod="checkLogin"pointcut-ref="myPointcut1"/>
<aop:aroundmethod="punchCard"pointcut-ref="myPointcut"/>
<aop:aftermethod="getUp"pointcut-ref="myPointcut"/>
<aop:after-returningmethod="back"pointcut-ref="myPointcut"/>
<aop:after-throwingmethod="unWell"pointcut-ref="myPointcut"throwing="ex"/>
<aop:declare-parentstypes-matching="*..EmployeeServiceBean"
implement-interface="cn.csdn.advice.Auditable"default-impl="cn.csdn.advice.AuditableAdvice"/>
</aop:aspect>
</aop:config>
7. Spring连接mysql数据库
1> 创建一个DataSource连接池
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>${driverClassName}</value>
</property>
<propertyname="url">
<value>${url}</value>
</property>
<propertyname="username">
<value>${username}</value>
</property>
<propertyname="password">
<value>${password}</value>
</property>
</bean>
<context:property-placeholderlocation="jdbc.properties"/>
2> jdbcTemplate模板类和nameedparamterJdbcTemplate模板类
<!-- jdbcTemplate模板类 -->
<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<!--nameedparamterJdbcTemplate模板类 -->
<beanid="namedParameterJdbcTemplate"class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
3> 注入
<!-- 注入到Dao操作实现类中 -->
<beanid="adminDaoImpl"class="cn.csdn.dao.AdminsDaoImpl">
<!--注入模板类对象 -->
<propertyname="jdbcTemplate"ref="jdbcTemplate"/>
</bean>
<beanid="adminDaoNamedImpl"class="cn.csdn.dao.AdminDaoNamedImpl">
<!--注入模板类对象 -->
<propertyname="namedParameterJdbcTemplate"ref="namedParameterJdbcTemplate"/>
</bean>