Spring---AOP註解開發&jdbc模板&Spring交易管理,spring---aop註解
一、AOP註解開發
此處需要回憶一遍AOP的概念。簡單的來說,AOP就是利用動態代理技術,做到不觸動原始碼但卻擴充了功能。那麼就需要一個被擴充的對象和一個“新的功能”,例如說給某類的saveUser方法增加輸出日誌需求,此時輸出日誌該事件就是一個“新的功能”。舉這個例子的重點只是為了突出,AOP技術需要關注兩個方面,一個是接受者,而另一個是輸出點。要利用AOP,必然需要將這兩個對象做出關聯。而所謂AOP註解開發,就是如何將這兩個對象建立關係。
當然,以上理解僅僅為個人的話語解讀,不具有嚴謹的用詞,有任何理解錯誤,望不吝賜教。
在AOP的xml開發中,xml核心配置如下
<aop:config> <--切入點(接受對象)--> <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="aa"/> <--切面(新功能)--> <aop:aspect ref="logger"> <aop:before method="log" pointcut-ref="aa"/> </aop:aspect></aop:config>
因此,註解只需要做到清楚表達以上兩點內容,再配套一些基本的要求,例如託管類。此外,為了讓程式的複用性更強,我們只需要對“新功能”對象做處理,告訴它要為誰增強方法即可做到關聯,以下為執行個體:
- 匯入jar包 aop聯盟包、 aspectJ實現包 、 spring-aop-xxx.jar 、 spring-aspect-xxx.jar
- 導aop約束 ,開啟掃描約束開關<aop:aspectj-autoproxy/>
- 託管兩個類,在類上加註解@Compone
- 然後再“新的功能”類上配置註解
@Aspect //這個註解,是和aop有關,用於表示該類是一個功能擴充類,專門用來做增強。public class Logger { @Before("execution(* com.gaga.service.impl.*.*(..))") public void log(){ System.out.println("輸出日誌了~~~!"); }
二、jdbc模板
所謂jdbc模板,就是Spring對於dao層的支援人員。和DBUtils的功能的目的是一樣的,就是為了操作資料庫。回想以下,如果什麼架構都沒有,只有java原生代碼提供給我們的prepareStatement、createStatement、遍曆resultSet那一套東西。那我們的操作便會過於臃腫。
雖然操作資料庫有更專業的架構,例如Hibernate\Mybatis等等。但作為一個負責Service層的架構,自然會有向兩邊擴充的思想,因此便有了該部分模板。
spring其實對dao層的大部分技術有提供模板支援
public void testDemo(){ //資料來源,連資料庫。 連什麼類型的資料, 哪個庫, 帳號 & 密碼 DriverManagerDataSource dataSource =new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///stus"); dataSource.setUsername("root"); dataSource.setPassword("root"); //1. 建立jdbc模板 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); String sql = "insert into t_user values(null , ? , ? )"; //2. 執行添加操作,其實它的用法和以前的queryrunner一樣。 jdbcTemplate.update(sql , "66666","zhangsan"); }
2.配置C3P0串連池(注入寫法)
為了方便修改資料庫連接資訊,通常在src下使用properties檔案來記錄他們。主要是方便修改
- 匯入Jar包 c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
- 配置xml
- 在src下建立一個properties檔案,內容如下 名:jdbc.properties
driverClass=com.mysql.jdbc.DriverjdbcUrl=jdbc:mysql:///useruser=rootpassword=root
以上配置將service\dao\jdbcTemplate\串連池都用IOC做了託管,並且用了DI注入,也就是說1.例子中的一堆堆代碼可以簡化為如下。只需要聲明模板,然後直接可以使用,建立對象什麼的都交給Spring。核心便是這個
@Repository("ud")public class UserDaoImp implements UserDao { @Autowired private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { System.out.println("userDao的set方法---"); this.jdbcTemplate = jdbcTemplate; } @Override public void save() { String sql = "insert into bbb values(null,?)"; jdbcTemplate.update(sql, "66666666"); }}
三、Spring交易管理
正如標題所述,Spring會對事務做管理。但需要注意只是做管理,實際操作還是依據不同的架構的做法(不同的實現)。
這裡不得不提,Spring其中的偉大之一在於AOP。那麼我們就可以利用它來對某部分功能加入事務的功能。而,當我們要利用Spring來進行交易管理的時候,正所謂人在屋簷下,不得不低頭。你用人家的,那也得遵守別人定下的規矩。
Spring統一規定,要操作事務,必須使用管理員!
管理事務的規範是 : PlatformTransactionManager jdbc | mybatis : DataSourceTransactionManager hibernate : HibernateTransactionManager
Spring對事務的支援,有三種寫法:編程式事務、xml聲明式事務、註解聲明式事務。
這三種寫法中,最簡介的為註解式事務。以下列出三種寫法的執行個體,推薦後者。
- 編程式事務
1 @Test 2 public void test(){ 3 4 5 //事務的管理員是用來管理事務的,包含了開啟事務、 提交事務、 復原事務 6 final DriverManagerDataSource dataSource = new DriverManagerDataSource(); 7 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 8 dataSource.setUrl("jdbc:mysql:///stus"); 9 dataSource.setUsername("root");10 dataSource.setPassword("root");11 12 13 DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();14 transactionManager.setDataSource(dataSource);15 16 //1. 建立事務的模板對象。17 TransactionTemplate transactionTemplate = new TransactionTemplate();18 transactionTemplate.setTransactionManager(transactionManager);19 20 //事務事務的模板對象21 transactionTemplate.execute( new TransactionCallback<Object>() {22 23 //在事務裡面執行這個方法。24 @Override25 public Object doInTransaction(TransactionStatus arg0) {26 27 //添加操作28 JdbcTemplate jdbcTemplate = new JdbcTemplate();29 jdbcTemplate.setDataSource(dataSource);30 31 String sql = "insert into t_user values ( null , ? , ?)";32 jdbcTemplate.update(sql, "123","王五");33 34 int a = 1 / 0 ;35 36 jdbcTemplate.update(sql, "6666","趙六");37 38 return null;39 }40 });41 42 }
編程式事務
- xml聲明式事務
1 <!-- 以下屬於事務的配置 如果要用事務了,那麼事務的管理員是誰啊。 --> 2 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 3 <property name="dataSource" ref="dataSource"></property> 4 </bean> 5 6 <!-- 7 以上配置,到目前為止,只是說明了,如果要開啟事務,管理員是誰。 但是缺少了一個東西。 8 就是哪一個方法到底要用事務呀? --> 9 <aop:config>10 <aop:pointcut expression="execution(* com.gaga.service.impl.*.*(..))" id="aa"/> 11 <aop:advisor advice-ref="advice01" pointcut-ref="aa"/>12 </aop:config>13 14 <tx:advice id="advice01" transaction-manager="transactionManager">15 <tx:attributes> <!-- 對 id="aa"運算式找到的那一堆方法,進行過濾配置,表示誰才能用交易管理, 如果是* ,表示前面找到的那一堆都用交易管理 -->16 <tx:method name="save*"/>17 <tx:method name="update*"/>18 <tx:method name="delete*"/>19 </tx:attributes>20 </tx:advice>
xml聲明式事務
a)xml中的配置
<context:component-scan base-package="gaga"/> <aop:aspectj-autoproxy/>1. 在xml中 聲明註解事務的管理員<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driverClass}"/> <property name="jdbcUrl" value="${jdbcUrl}"/> <property name="user" value="${user}"/> <property name="password" value="${password}"/> </bean> <!-- 以下屬於事務的配置 如果要用事務了,那麼事務的管理員是誰啊。 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 指定註解事務使用的管理員是誰 --> <tx:annotation-driven transaction-manager="transactionManager"/>
b) 代碼配置
2. 在商務邏輯類上或者方法上打註解 類上的註解,表示類中的所有方法都用事務, 如果在方法上打註解,表示只有這個方法才會用事務 @Transactional public class UserServiceImpl implements UserService { } public class UserServiceImpl implements UserService { // @Transactional @Override public void save() { }