spring切入点详解

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

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