spring aop

一,spring实现aop

1,基于注解

<aop:aspectj-autoproxy />

xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"

//启动对@AspectJ注解的支持
<aop:aspectj-autoproxy />

2,基于xml配置

<aop:config>...

二,spring与jdbc整合

//专门用来对@Transactional解析,注解本身是不起作用的

<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />

首先引入一些要用的包

spring框架需要:

commons-logging.jar
spring.jar

注解需要:

aspectjrt.jar

aspectjweaver.jar
cglib-nodep-2.1_3.jar
common-annotations.jar


jdbc数据库,连接池需要:
commons-dbcp-1.2.1.jar
commons-pool-1.6.jar
mysql-connector-java-5.1.29-bin.jar

一,注解配置事务

1,在beans.xml中


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"  
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

属性名是固定的,如driverClassName

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="org.gjt.mm.mysql.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/test" />            
            <property name="username" value="root" />
            <property name="password" value="root" />
            连接池启动时的初始值 
            <property name="initialSize" value="1"/>
            空闲时,经过高峰时间后,连接池慢慢释放空闲连接,一直减少到maxidle,就停止释放 
            <property name="maxIdle" value="2" />
            最小空闲数,当空闲的连接数小于阈值时,连接池就会预申请一些连接,避免高峰期来不及申请 
            <property name="minIdle" value="1" />
            连接池的最大数 
            <property name="maxActive" value="10" />            
        </bean>
        <!--配置事务管理器  -->
         <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
             <property name="dataSource" ref="dataSource" />
         </bean>
         <bean id="personService" class="com.maple.service.impl.PersonServiceBean">
             <property name="dataSource" ref="dataSource"></property>
         </bean>
         <!--用于解析@Transactional注解,注解本身无作用  -->
         <tx:annotation-driven transaction-manager="txManager"/>
</beans>

2,PersonService是接口,PersonServiceBean实现了接口,Person是实体类,mysql数据库中有对应表Person,数据库名是test

package com.maple.service.impl;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.maple.bean.Person;
import com.maple.service.PersonService;

public class PersonServiceBean implements PersonService {
    //private DataSource dataSource;
    private JdbcTemplate jdbcTemplate;
    public void setDataSource(DataSource dataSource) {
        //this.dataSource = dataSource;
        jdbcTemplate=new JdbcTemplate(dataSource);
    }

    @Override
    public void save(Person p) {
        // TODO Auto-generated method stub
        jdbcTemplate.update("insert into person (name) values (?)", 
                new Object[]{p.getName()}, 
                new int[]{java.sql.Types.VARCHAR});
    }

    @Override
    public Person getPerson(Integer id) {
        // TODO Auto-generated method stub
        return (Person) jdbcTemplate.queryForObject("select * from person where id=?",
                new Object[]{id}, new PersonRowMapper());
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Person> getPersons() {
        // TODO Auto-generated method stub
        return jdbcTemplate.query("select * from person",new PersonRowMapper());
    }

    @Override
    public void update(Person p) {
        // TODO Auto-generated method stub
        jdbcTemplate.update("update person set name=? where id=?",
                new Object[]{p.getName(),p.getId()},
                new int[]{java.sql.Types.VARCHAR,java.sql.Types.INTEGER});
    }

    @Override
    public void delete(Integer id) {
        // TODO Auto-generated method stub
        jdbcTemplate.update("delete from person where id=?",
                new Object[]{id},new int[]{java.sql.Types.INTEGER});
    }

}

如果数据库连接池的配置要单独放在属性文件中

<context:property-placeholder location="classpath:jdbc.properties"/>  //属性占位符,指明属性文件在类路径下
       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${driverClassName}" />
            <property name="url" value="${url}" />            
            <property name="username" value="${username}" />
            <property name="password" value="${password}" />
            <!--连接池启动时的初始值  -->
            <property name="initialSize" value="${initialSize}"/>
            <!--空闲时,经过高峰时间后,连接池慢慢释放空闲连接,一直减少到maxidle,就停止释放  -->
            <property name="maxIdle" value="${maxIdle}" />
            <!--最小空闲数,当空闲的连接数小于阈值时,连接池就会预申请一些连接,避免高峰期来不及申请  -->
            <property name="minIdle" value="${minIdle}" />
            <!--连接池的最大数  -->
            <property name="maxActive" value="${maxActive}" />            
        </bean>  

jdbc.properties

driverClassName=org.gjt.mm.mysql.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root
initialSize=1
maxIdle=2
minIdle=1
maxActive=10

就可以了

 unchecked Exceptin:运行期异常,事务会回滚

checked Exception:事务不会回滚

Unchecked Exception.:包括 Error与RuntimeException. 这类异常都是RuntimeException的子类。

Checked Exception:除了Error与RuntimeException,其他剩下的异常. 这类异常都是Exception的子类 。在编译时在语法上必须处理的异常,因此必须在语法上以try..catch加以处理;

一,

1,会抛异常,记录不会删除,即事务会回滚,unchecked Exception

@Override
    public void delete(Integer id)  {
        // TODO Auto-generated method stub
        jdbcTemplate.update("delete from person where id=?",
                new Object[]{id},new int[]{java.sql.Types.INTEGER});
        throw new RunTimeException("运行时异常");
    }

//在junit中
@Test
    public void delete(){
        personService.delete(6);
    }

2,会抛异常,记录会删除,事务不会回滚,checked Exception

@Override
    public void delete(Integer id) throws Exception {
        // TODO Auto-generated method stub
        jdbcTemplate.update("delete from person where id=?",
                new Object[]{id},new int[]{java.sql.Types.INTEGER});
        throw new Exception("运行时异常");
    }

@Test
    public void delete(){
        //Person p=personService.getPerson(1);
        try {
            personService.delete(6);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

针对2,默认不回滚,改变他的回滚方式,即使出现checked Exception,也让事务回滚,使得记录不会删除

@Transactional(rollbackFor=Exception.class)
    @Override
    public void delete(Integer id) throws Exception {
        // TODO Auto-generated method stub
        jdbcTemplate.update("delete from person where id=?",
                new Object[]{id},new int[]{java.sql.Types.INTEGER});
        throw new Exception("运行时异常");
    }

 针对1,默认会回滚 ,可以让他不回滚

@Transactional(noRollbackFor=RuntimeException.class)
    @Override
    public void delete(Integer id) throws Exception {
        // TODO Auto-generated method stub
        jdbcTemplate.update("delete from person where id=?",
                new Object[]{id},new int[]{java.sql.Types.INTEGER});
        throw new RuntimeException("运行时异常");
    }

二,xml配置事务,spring事务管理

如果没有纳入到spring的事务管理器中,则是处于各自不同的事务中

如果在spring的事务管理中,则是一个事务

要在beans.xml进行配置

<!--配置事务管理器  -->
         <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
             <property name="dataSource" ref="dataSource" />
         </bean>
         <bean id="personService" class="com.maple.service.impl.PersonServiceBean">
             <property name="dataSource" ref="dataSource"/>
         </bean>
         <!--用于解析@Transactional注解,注解本身无作用  -->
         <!-- <tx:annotation-driven transaction-manager="txManager"/> -->
         <aop:config>
             <aop:pointcut expression="execution(* com.maple.service..*.*(..))" 
             id="transactionPointcut"/>
             <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
             
         </aop:config>
         <tx:advice id="txAdvice" transaction-manager="txManager">
             <tx:attributes>
                 <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
                 <tx:method name="*" />
             </tx:attributes>
         </tx:advice>

888888888

有问题在公众号【清汤袭人】找我,时常冒出各种傻问题,然一通百通,其乐无穷,一起探讨


原文地址:https://www.cnblogs.com/qingmaple/p/4082268.html