spring-day4

来源:互联网 发布:南京网络问政开发区 编辑:程序博客网 时间:2024/05/16 17:27
第四天:

1  aop:config标签
   使用aop的专用标签来完成相关的配置.
   其中主要表现是使用AspectJ的expression的操作:
   execution(modifiers-pattern ret-type-pattern declaring-type-pattern name-pattern(param-pattern) throws-pattern)除了返回类型模式,名字模式和参数模式以外,所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 *,它代表了匹配任意的返回类型。 一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 * 通配符作为所有或者部分命名模式。 参数模式稍微有点复杂:() 匹配了一个不接受任何参数的方法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。 模式 (*) 匹配了一个接受一个任何类型的参数的方法。 模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型
   
   注意在使用之前需要在xml文件的beans标签中加入新的schame文件:并在Eclipse中进行关联配置
   <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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.2.xsd">


   下面给出一些常见切入点表达式的例子。  

 
   1)任意包下的任意类中的公共方法的执行:  
      execution(public * *(..))
   2)任何一个以“set”开始的方法的执行:  
      execution(* set*(..))
   3)AccountService 接口的任意方法的执行:    
      execution(* com.briup.service.AccountService.*(..))
   4)定义在service包里的任意方法的执行:  
      execution(* com.briup.service.*.*(..))
   5)定义在service包或者子包里的任意方法的执行:  
      execution(* com.briup.service..*.*(..))
   6)在service包里的任意连接点(在Spring AOP中只是方法执行)
      within(com.xyz.service.*)
   7)在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :  
      within(com.xyz.service..*)



   注意:  1.从spring容器中拿代理对象的时候也是要用目标对象的名字来拿。
      2.没有实现任何接口的目标对象也能产生代理对象。
    
        <!-- 配置aop的代理 -->
    <aop:config>
        <!-- 定义一个切入点 并给切入点起名为myPointCut -->
        <!-- 切入点是一组连接点的集合 -->
        <aop:pointcut expression="execution(public * com.briup.aop.service.*.*(..))" id="myPointCut"/>

        <!-- 定义哪一个advice在哪一个切入点上面起作用 -->
        <aop:advisor advice-ref="beforeAdvice" pointcut-ref="myPointCut" />
    </aop:config>
    <!--
        expression="execution(public * com.briup.spring.aop.service.*.*(..))"
        这个引号""里面就是用表达式的方式来定义切入点,只要是符合我们这个表达式要求的
        方法就是我们的连接点,连接点的集合就是我们要定义的切入点。
        表达式中从左到右的*号:
            第一个* 表示方法的返回类型不限。
            第二个* 表示包中的任意一个类
            第三个* 表示类中的任意一个方法
            
        同时方法的参数也没有限制.
     -->

2  在一个切面类中定个多个方法,根据xml文件的配置每个方法都可以织入到切入点的不同位置,并且advice是在aop的标签中进行配置,不需要再写对应的advice类了
   例如:
    //这个类相当于我们之前的切面类
    //只不过这个切面类中有很多方法都可以织入到切入点上面
    //我们可以控制把这里的任何一个方法织入到任何一个切入点上面
    public class XmlHandler {
        
        public void beforeTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" before...");
        }
        
        
        public void afterTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" after...");
        }
        
        public void afterReturningTest(JoinPoint p){
            
            System.out.println(p.getSignature().getName()+" afterReturning");
            
        }
        
        //在和aroundAdvice结合的时候,这个方法一定要加上这个ProceedingJoinPoint类型的参数
        public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{
            //JoinPoint对象不能调用连接点所表示的方法
            //ProceedingJoinPoint能调用连接点所表示的方法 pjp.proceed()
            System.out.println(pjp.getSignature().getName()+" is start..");
            //调用到连接点方法
            Object obj = pjp.proceed();
            System.out.println(pjp.getSignature().getName()+" is end..");
            return obj;
        }
        
        public void throwingTest(JoinPoint p,Exception ex){
            System.out.println(p.getSignature().getName()+" is throwing..."+ex.getMessage());
            
        }
    }
    
        xml文件配置:
    <!-- 配置dao层对象 -->
    <bean id="dao"
        class="com.briup.aop.dao.AccountDaoImpl"/>
     <!-- 配置目标对象 -->
    <bean name="target"
    class="com.briup.aop.service.AccountServiceImpl">
            <property name="accountDao" ref="dao"></property>
    </bean>
    <!-- 配置切面类 -->
    <bean name="handler" class="com.briup.aop.xml.XmlHandler"></bean>
    
    <!-- 配置aop的代理 -->
    <aop:config>
        <!-- 定义切入点名为myPointCut -->
        <aop:pointcut expression="execution(public * com.briup.aop.service.*.*(..))" id="myPointCut"/>
        
        <!-- 定义切面类 以及需要使用的advice -->
        <aop:aspect id="aspect" ref="handler">
            <!-- 表示beforeAdvice会把切面类handler中的beforeTest方法织入到名字叫myPointCut的切入点上面 -->
            <aop:before method="beforeTest" pointcut-ref="myPointCut"/>

            <!-- after表示不管方法是否正常结束都会起作用 -->
            <aop:after method="afterTest" pointcut-ref="myPointCut"/>

            <!-- after-returning表示方法正常结束才会起作用(抛异常时候不起作用) -->
            <aop:after-returning method="afterReturningTest" pointcut-ref="myPointCut"/>

            <aop:around method="aroundTest" pointcut-ref="myPointCut"/>

            <!-- throwing="ex"表示throwingTest方法中接收异常对象的名字一定要是ex -->
            <aop:after-throwing method="throwingTest" pointcut-ref="myPointCut" throwing="ex"/>

        </aop:aspect>
    </aop:config>



3  使用注解配置AOP:其实就是在上面的类XmlHandler中加入上注解然后去掉xml中的aop标签配置,这里把类改名为AnnotationHandler,
   例子:
    @Component
    @Aspect
    public class AnnotationHandler {
        /*
         * 在一个方法上面加上注解来定义切入点
         * 这个切入点的名字就是这个方法的名字
         * 这个方法本身不需要有什么作用
         * 这个方法的意义就是:给这个 @Pointcut注解一个可以书写的地方
         * 因为注解只能写在方法、属性、类的上面,并且方法名作为切入点的名字
         * */
        @Pointcut("execution(public * com.briup.aop.service..*.*(..))")
        public void myPointCut(){}
        
        //注:这里面的所有方法的JoinPoint类型对象都可以去掉不写
        @Before("myPointCut()")
        public void beforeTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" before...");
        }
        
        
        /*
         * @After和@AfterReturning
         *
         * @After标注的方法会在切入点上的方法结束后被调用(不管是不是正常的结束).
         * @AfterReturning标注的方法只会在切入点上的方法正常结束后才被调用.
         * */
        @After("myPointCut()")
        public void afterTest(JoinPoint p){
            System.out.println(p.getSignature().getName()+" after...");
        }
        @AfterReturning("myPointCut()")
        public void afterReturningTest(JoinPoint p){
            
            System.out.println(p.getSignature().getName()+" afterReturning");
            
        }
        
        @Around("myPointCut()")
        public Object aroundTest(ProceedingJoinPoint pjp)throws Throwable{
            System.out.println(pjp.getSignature().getName()+" is start..");
            //调用连接点的方法去执行
            Object obj = pjp.proceed();
            System.out.println(pjp.getSignature().getName()+" is end..");
            return obj;
        }
        
        
        
        //在切入点中的方法执行期间抛出异常的时候,会调用这个 @AfterThrowing注解所标注的方法
        @AfterThrowing(value="myPointCut()",throwing="ex")
        public void throwingTest(JoinPoint p,Exception ex){
            System.out.println(p.getSignature().getName()+" is throwing..."+ex.getMessage());
            
        }
        
        
    }
    
    xml配置:注意给例子中使用的其他的类上面也使用注解
    <aop:aspectj-autoproxy/>
    <context:component-scan base-package="com.briup.aop"/>


4  Spring与jdbc结合
   jdbc编程不变,主要是Connection对象的维护,即配置并使用数据源
   1)   <!-- 基于jdk的规范数据源 -->
        <bean name="dataSource1"
        class="oracle.jdbc.pool.OracleConnectionPoolDataSource">
        <property name="networkProtocol">
            <value>tcp</value>
        </property>
        <property name="databaseName">
            <value>XE</value>
        </property>
        <property name="driverType">
            <value>thin</value>
        </property>
        <property name="portNumber">
            <value>1521</value>
        </property>
        <property name="user">
            <value>briup</value>
        </property>
        <property name="serverName">
            <value>127.0.0.1</value>
        </property>
        <property name="password">
            <value>briup</value>
        </property>
    </bean>


   注意:别忘了读取配置文件
    <!-- 读取这个资源文件 读完之后下面就可以用${key}来去文件中的value值了 -->
    <!-- 这种方式是我们第一节学习的那种配置方式方式的简写 -->
    <context:property-placeholder location="com/briup/db/jdbc/jdbc.properties"/>

   2)    <!-- dbcp数据源 -->
    <bean id="dataSource2"
        class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="username">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
        <!-- 最大连接数 -->
        <property name="maxActive">
            <value>80</value>
        </property>
        <!-- 最大空闲连接数 -->
        <property name="maxIdle">
            <value>20</value>
        </property>
        <!-- 最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间 单位:毫秒 -->
        <!-- 超过时间则抛出异常,如果设置为-1表示无限等待 -->
        <property name="maxWait">
            <value>3000</value>
        </property>
    </bean>

   3)  <!-- spring提供的一种数据源 -->
       <bean id="dataSource3"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="username">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
      </bean>

    spring在jdbc的使用中还给我们提供了一个模板类:JdbcTemplate
    用以简化我们的jdbc操作
    例如:
    //使用xml进行配置时候的java类中的写法:
    public class JdbcTemplateDao implements AccountDao{
    private JdbcTemplate jdbcTemplate;
    
    //只要类中有set方法 在xml文件就可以进行配置和注入
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    ...
    }
   
    //使用注解进行配置时候的java类中的写法:
    @Repository
    public class JdbcTemplateDao implements AccountDao {

        private JdbcTemplate jdbcTemplate;

        @Autowired
        public void setDataSource(DataSource dataSource) {
                this.jdbcTemplate = new JdbcTemplate(dataSource);
        }
    ....
    ...
    }

    注意:JdbcTemplate模板类如何使用:在htmlsingle中搜索即可,其中包含有大量的使用实例



5  Spring与Hibernate结合
   使用Spring整合Hibernate时我们可以不需要hibernate.cfg.xml文件。
   
   重点在于配置sessionFactory
    <!-- 配置sessionFactory -->
    <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
        name="sessionFactory">
        <!-- 注入数据源 -->
        <property name="dataSource">
               <ref local="dataSource"/>
        </property>
        <!-- 注入映射文件-->
        <property name="mappingResources">
               <list>
                    <value>com/briup/db/hibernate/account.hbm.xml</value>
               </list>
        </property>
        <!-- 注入hibernate的属性信息-->
        <property name="hibernateProperties">
               <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
               </props>
        </property>
    </bean>
        
    或者:

    <!-- 配置sessionFactory -->
    <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
        name="sessionFactory">
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
    </bean>

    结合hibernate的配置xml例子:
        <bean id="account" class="com.briup.db.Account"/>
    
    <!-- 配置sessionFactory -->
    <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
        name="sessionFactory">
         <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
         </property>
    </bean>
    <!-- 配置dao层对象 -->
    <bean name="accountDao"
          class="com.briup.db.hibernate.Spring_Hibernate">
          <!-- 注入sessionFactory对象 -->
          <property name="sessionFactory">
             <ref bean="sessionFactory" />
          </property>
      </bean>
      
      <!-- 配置hibernate的事务管理器 相当于aop配置中的切面类-->
      <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
          <!-- 注入sessionFactory对象 -->
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
    </bean>
    
    <!-- 配置事务拦截器 相当于aop配置中advice-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 配置在些方法上面加入哪些事务属性 以及抛出什么异常的时候回滚-->
            <tx:method name="with*" propagation="REQUIRED" rollback-for="Throwable"/>
            <tx:method name="depo*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- 上面配置了切面类以及advice -->
    <!-- 这里就要做aop的配置了 -->
    <aop:config>
        <!-- 配置切入点 -->
        <aop:pointcut id="myPointCut"
        expression="execution(* com.briup.db.hibernate..*.*(..))"/>
        <!-- 配置事务拦截器在哪一个切入点上起作用 -->
        <aop:advisor pointcut-ref="myPointCut" advice-ref="txAdvice"/>
    </aop:config>

    和jdbc类似的spirng也提供了hibernate的模板类的使用:HibernateTemplate
    使用过程和jdbc的模板类差不多,在htmlsingle有实例说明




0 0
原创粉丝点击