spring切入点详解

时间:2021-11-25 09:46:48

                   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.jaraspectjweaver.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>