Spring学习(三)

Spring学习笔记(14)----使用CGLIB实现AOP功能
-----------------------------------------------
 
接着这上面的例子,在上面的例子中我们的UserManagerImpl类是实现了UserManager接口,如果UserManagerImpl没有实现任何接口要怎么办呢?应为创建代理对象时我们需要指定接口的。
  
 
 
Java代码 
1.Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
2.                                      targetObject.getClass().getInterfaces(), 
3.                                     this); 
  
  
  
由于没有时间接口,因此我们是不能这样创建代理接口的,这是我们需要借助第三方包来实现。在spring中提供了cglib-nodep-2.1_3.jar包。我们通过cglib创建代理对象。
  
下面就通过实例演示通过cglib创建代理对象。
  
  
  
首先创建CGlibProxyFactory,实现MethodInterceptor接口,接口中有一个intercept方法,当代理对象的方法被调用时会调用这个方法。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.import java.lang.reflect.Method; 
4.import net.sf.cglib.proxy.Enhancer; 
5.import net.sf.cglib.proxy.MethodInterceptor; 
6.import net.sf.cglib.proxy.MethodProxy; 
7
8
9.public class CGlibProxyFactoryimplements MethodInterceptor 
10.{ 
11.   private Object targetObject; 
12.     
13.   public Object newProxy(Object targetObject) 
14.    { 
15.       this.targetObject=targetObject; 
16.        Enhancer enhancer=new Enhancer(); 
17.        enhancer.setSuperclass(this.targetObject.getClass()); 
18.        enhancer.setCallback(this); 
19.       //返回代理对象 
20.       return enhancer.create(); 
21.    } 
22
23.   /**
24.     * proxy        带来对象本身
25.     * method       被拦截到的方法
26.     * args          方法的参数
27.     * methodProxy  方法的代理对象
28.     */ 
29.   public Object intercept(Object proxy, Method method, Object[] args, 
30.            MethodProxy methodProxy) throws Throwable 
31.    { 
32.        checkSecurity(); 
33.        Object ret=null
34.       try 
35.        { 
36.           //调用目标对象的真实方法 
37.            ret=method.invoke(this.targetObject, args); 
38.           //ret接受存在的返回值,不存在返回值则为Null 
39.        } catch (Exception e) 
40.        { 
41.            e.printStackTrace(); 
42.        } 
43.       return ret; 
44.    } 
45.   public void checkSecurity() 
46.    { 
47.        System.out.println("--------UserManagerImpl.checkSecurity()----------"); 
48.    } 
49.} 
  
  
  
其实整个代码很前面的很相似,只是创建代理对象的方法不一样。
  
测试代码:
  
 
 
Java代码 
1.CGlibProxyFactory factory=new CGlibProxyFactory(); 
2.       //创建代理对象,这是这个代理对象是UserManagerImpl的子类 
3.        UserManagerImpl userManager=(UserManagerImpl)factory.newProxy(new UserManagerImpl()); 
4.        userManager.addUser("coolszy","kuka"); 
  
  
  
上面演示的几个事例是不借助与任何框架的情况下实现AOP的方法。
 
 
 
 
 
 
 
Spring学习笔记(15)----使用Spring的注解方式实现AOP
-----------------------------------------------------
下面介绍使用Spring框架进行AOP编程。
  
首先我们需要导入需要的jar包:
  
1.aspectjrt.jar
  
2.aspectjweaver.jar
  
3.cglib-nodep-2.1_3.jar
  
  
  
在spring中有两种方式实现面向切面编程,一种是基于XML配置,另一种是使用注解份额方式,在实际开放中我们可以任选其中的一种即可。
  
  
  
首先介绍下使用注解方式进行AOP开发。
  
要使用注解方式,我们需要打开注解处理器
  
 
 
Xml代码 
1.<aop:aspectj-autoproxy/> 
  
我们还是使用前面介绍的接口:
  
  
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public interface UserManager 
4.{ 
5
6.   public abstract void addUser(String username, String password); 
7
8.   public abstract void deleteUser(int userId); 
9
10.   public abstract String findUser(int userId); 
11
12.   public abstract void modifyUser(int userId, String username, String password); 
13
14.} 
  
  
  
实现这个接口:
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public class UserManagerImplimplements UserManager  
4.{ 
5
6.   public void addUser(String username, String password) 
7.    { 
8.        System.out.println("--------UserManagerImpl.addUser()----------"); 
9.    } 
10
11.   public void deleteUser(int userId) 
12.    { 
13.        System.out.println("--------UserManagerImpl.deleteUser()----------"); 
14.    } 
15
16.   public String findUser(int userId) 
17.    { 
18.        System.out.println("--------UserManagerImpl.findUser()----------"); 
19.       return null
20.    } 
21
22.   public void modifyUser(int userId, String username, String password) 
23.    { 
24.        System.out.println("--------UserManagerImpl.modifyUser()----------"); 
25.    } 
26.} 
  
  
  
下面我们定义一个切面类,由于我们使用的是注解方式,因此我们使用@Aspect来标识它是切面类。在切面类中我们要定义切入点,切入点是用来定义我们要拦截的方法。在切入点定义中使用了AOP表达式语言,下面通过实例简单解释一下:
  
  
  
 
 
表达式解释代码 
1.@Pointcut("execution (* com.szy.spring..*.*(..))"
2.execution:代表执行 
3.第一个*:代表返回值类型,使用*代表任何类型的返回值 
4.com.szy.spring:代表包名 
5...:代表其底下的子包也进行拦截 
6.第二个*:代表对哪个类进行拦截,*代表所有类 
7.第三个*:代表方法 
8.(..):代表方法的蚕食有无都可以 
  
  
  
现在我们要对UserManagerImpl类下的所有方法进行拦截,则切入点如下表示:
  
 
 
Java代码 
1.@Pointcut("execution (* com.szy.spring.UserManagerImpl.*(..))"
2
3.private void anyMethod() //定义切入点 
4. { 
5. } 
  
  
  
其中切入点的名称是下面方法的名称aynMethod(),包括括号。
  
  
  
下面我们定义通知,通知分为前置通知、后置通知、意外通知、等。通知分为前置通知、后置通知、意外通知、最终通知和环绕通知等。
  
演示前置通知,
  
 
 
Java代码 
1.@Before("anyMethod()")//括号内为切入点名称 
2public void doBefore() 
3.  { 
4.   System.out.println("----------------执行前置通知-----------------"); 
5.  } 
6.  
7@AfterReturning("anyMethod()"
8public void doAfterReturning() 
9.  { 
10.   System.out.println("----------------执行后置通知-----------------"); 
11.  } 
  
 
 
Java代码 
1.@After("anyMethod()"
2.public void doAfter() 
3. { 
4.  System.out.println("----------------执行最终通知-----------------"); 
5. } 
6.  
7@AfterThrowing("anyMethod()"
8public void doAfterThrowing() 
9.  { 
10.   System.out.println("----------------执行意外通知-----------------"); 
11.  } 
12.   
13.@Around("anyMethod()"
14.public Object doAround(ProceedingJoinPoint pjp) throws Throwable 
15. { 
16.  System.out.println("----------------进入判断方法-----------------"); 
17.  Object result=pjp.proceed();  //该方法必须被执行 
18.  System.out.println("----------------退出判断方法-----------------"); 
19return result; 
20. } 
  
  
  
 我们把切面交给spring管理,要交给spring管理我们可以在配置文件同进行bean配置,或者使用扫描的方式。
  
 
 
Xml代码 
1.<bean id="interceptor" class="com.szy.spring.Interceptor"/> 
  
 下面我们进行测试
  
 
 
Java代码 
1.ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); 
2.        UserManager manager=(UserManager)context.getBean("userManager"); 
3.        manager.addUser("coolszy","kuka"); 
  
  
  
按照我们的设计,输入的结果应为
  
----------------执行前置通知-----------------
----------------进入判断方法-----------------
--------UserManagerImpl.addUser()----------
----------------执行后置通知-----------------
----------------执行最终通知-----------------
----------------退出判断方法-----------------
 
 
 
 
 
 
Spring学习笔记(16)----使用Spring配置文件实现AOP
----------------------------------------------
 
前面介绍了使用注解的方式,下面介绍使用配置文件的方式实现AOP。
  
使用配置方式,Interceptor类中不包含任何注解。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.import org.aspectj.lang.ProceedingJoinPoint; 
4
5.public class Interceptor 
6.{ 
7.   public void doBefore() 
8.    { 
9.        System.out.println("----------------执行前置通知-----------------"); 
10.    } 
11.     
12.   public void doAfterReturning() 
13.    { 
14.        System.out.println("----------------执行后置通知-----------------"); 
15.    } 
16.     
17.   public void doAfter() 
18.    { 
19.        System.out.println("----------------执行最终通知-----------------"); 
20.    } 
21.     
22.   public void doAfterThrowing() 
23.    { 
24.        System.out.println("----------------执行意外通知-----------------"); 
25.    } 
26.     
27.   public Object doAround(ProceedingJoinPoint pjp) throws Throwable 
28.    { 
29.        System.out.println("----------------进入判断方法-----------------"); 
30.        Object result=pjp.proceed();  //该方法必须被执行 
31.        System.out.println("----------------退出判断方法-----------------"); 
32.       return result; 
33.    } 
34.} 
  
 紧着这我们在配置文件中配置切面、切入点、通知等:
  
 
 
Xml代码 
1.<bean id="aspetbean" class="com.szy.spring.Interceptor"/> 
2.    <aop:config> 
3.        <aop:aspect id="aspet" ref="aspetbean"
4.            <aop:pointcut id="cut" expression="execution (* com.szy.spring.UserManagerImpl.*(..))"/> 
5.            <aop:before pointcut-ref="cut" method="doBefore"/> 
6.            <aop:after-returning pointcut-ref="cut" method="doAfterReturning"/> 
7.            <aop:after pointcut-ref="cut" method="doAfter"/> 
8.            <aop:after-throwing pointcut-ref="cut" method="doAfterThrowing"/> 
9.            <aop:around pointcut-ref="cut" method="doAround"/> 
10.        </aop:aspect> 
11.    </aop:config> 
  
 运行测试代码输入正常结果。
  
在实际开发中AOP一般用于权限设置等。
  
  
 
 
 

Spring学习笔记(14)----使用CGLIB实现AOP功能
-----------------------------------------------
 
接着这上面的例子,在上面的例子中我们的UserManagerImpl类是实现了UserManager接口,如果UserManagerImpl没有实现任何接口要怎么办呢?应为创建代理对象时我们需要指定接口的。
  
 
 
Java代码 
1.Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
2.                                      targetObject.getClass().getInterfaces(), 
3.                                     this); 
  
  
  
由于没有时间接口,因此我们是不能这样创建代理接口的,这是我们需要借助第三方包来实现。在spring中提供了cglib-nodep-2.1_3.jar包。我们通过cglib创建代理对象。
  
下面就通过实例演示通过cglib创建代理对象。
  
  
  
首先创建CGlibProxyFactory,实现MethodInterceptor接口,接口中有一个intercept方法,当代理对象的方法被调用时会调用这个方法。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.import java.lang.reflect.Method; 
4.import net.sf.cglib.proxy.Enhancer; 
5.import net.sf.cglib.proxy.MethodInterceptor; 
6.import net.sf.cglib.proxy.MethodProxy; 
7
8
9.public class CGlibProxyFactoryimplements MethodInterceptor 
10.{ 
11.   private Object targetObject; 
12.     
13.   public Object newProxy(Object targetObject) 
14.    { 
15.       this.targetObject=targetObject; 
16.        Enhancer enhancer=new Enhancer(); 
17.        enhancer.setSuperclass(this.targetObject.getClass()); 
18.        enhancer.setCallback(this); 
19.       //返回代理对象 
20.       return enhancer.create(); 
21.    } 
22
23.   /**
24.     * proxy        带来对象本身
25.     * method       被拦截到的方法
26.     * args          方法的参数
27.     * methodProxy  方法的代理对象
28.     */ 
29.   public Object intercept(Object proxy, Method method, Object[] args, 
30.            MethodProxy methodProxy) throws Throwable 
31.    { 
32.        checkSecurity(); 
33.        Object ret=null
34.       try 
35.        { 
36.           //调用目标对象的真实方法 
37.            ret=method.invoke(this.targetObject, args); 
38.           //ret接受存在的返回值,不存在返回值则为Null 
39.        } catch (Exception e) 
40.        { 
41.            e.printStackTrace(); 
42.        } 
43.       return ret; 
44.    } 
45.   public void checkSecurity() 
46.    { 
47.        System.out.println("--------UserManagerImpl.checkSecurity()----------"); 
48.    } 
49.} 
  
  
  
其实整个代码很前面的很相似,只是创建代理对象的方法不一样。
  
测试代码:
  
 
 
Java代码 
1.CGlibProxyFactory factory=new CGlibProxyFactory(); 
2.       //创建代理对象,这是这个代理对象是UserManagerImpl的子类 
3.        UserManagerImpl userManager=(UserManagerImpl)factory.newProxy(new UserManagerImpl()); 
4.        userManager.addUser("coolszy","kuka"); 
  
  
  
上面演示的几个事例是不借助与任何框架的情况下实现AOP的方法。
 
 
 
 
 
 
 
Spring学习笔记(15)----使用Spring的注解方式实现AOP
-----------------------------------------------------
下面介绍使用Spring框架进行AOP编程。
  
首先我们需要导入需要的jar包:
  
1.aspectjrt.jar
  
2.aspectjweaver.jar
  
3.cglib-nodep-2.1_3.jar
  
  
  
在spring中有两种方式实现面向切面编程,一种是基于XML配置,另一种是使用注解份额方式,在实际开放中我们可以任选其中的一种即可。
  
  
  
首先介绍下使用注解方式进行AOP开发。
  
要使用注解方式,我们需要打开注解处理器
  
 
 
Xml代码 
1.<aop:aspectj-autoproxy/> 
  
我们还是使用前面介绍的接口:
  
  
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public interface UserManager 
4.{ 
5
6.   public abstract void addUser(String username, String password); 
7
8.   public abstract void deleteUser(int userId); 
9
10.   public abstract String findUser(int userId); 
11
12.   public abstract void modifyUser(int userId, String username, String password); 
13
14.} 
  
  
  
实现这个接口:
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public class UserManagerImplimplements UserManager  
4.{ 
5
6.   public void addUser(String username, String password) 
7.    { 
8.        System.out.println("--------UserManagerImpl.addUser()----------"); 
9.    } 
10
11.   public void deleteUser(int userId) 
12.    { 
13.        System.out.println("--------UserManagerImpl.deleteUser()----------"); 
14.    } 
15
16.   public String findUser(int userId) 
17.    { 
18.        System.out.println("--------UserManagerImpl.findUser()----------"); 
19.       return null
20.    } 
21
22.   public void modifyUser(int userId, String username, String password) 
23.    { 
24.        System.out.println("--------UserManagerImpl.modifyUser()----------"); 
25.    } 
26.} 
  
  
  
下面我们定义一个切面类,由于我们使用的是注解方式,因此我们使用@Aspect来标识它是切面类。在切面类中我们要定义切入点,切入点是用来定义我们要拦截的方法。在切入点定义中使用了AOP表达式语言,下面通过实例简单解释一下:
  
  
  
 
 
表达式解释代码 
1.@Pointcut("execution (* com.szy.spring..*.*(..))"
2.execution:代表执行 
3.第一个*:代表返回值类型,使用*代表任何类型的返回值 
4.com.szy.spring:代表包名 
5...:代表其底下的子包也进行拦截 
6.第二个*:代表对哪个类进行拦截,*代表所有类 
7.第三个*:代表方法 
8.(..):代表方法的蚕食有无都可以 
  
  
  
现在我们要对UserManagerImpl类下的所有方法进行拦截,则切入点如下表示:
  
 
 
Java代码 
1.@Pointcut("execution (* com.szy.spring.UserManagerImpl.*(..))"
2
3.private void anyMethod() //定义切入点 
4. { 
5. } 
  
  
  
其中切入点的名称是下面方法的名称aynMethod(),包括括号。
  
  
  
下面我们定义通知,通知分为前置通知、后置通知、意外通知、等。通知分为前置通知、后置通知、意外通知、最终通知和环绕通知等。
  
演示前置通知,
  
 
 
Java代码 
1.@Before("anyMethod()")//括号内为切入点名称 
2public void doBefore() 
3.  { 
4.   System.out.println("----------------执行前置通知-----------------"); 
5.  } 
6.  
7@AfterReturning("anyMethod()"
8public void doAfterReturning() 
9.  { 
10.   System.out.println("----------------执行后置通知-----------------"); 
11.  } 
  
 
 
Java代码 
1.@After("anyMethod()"
2.public void doAfter() 
3. { 
4.  System.out.println("----------------执行最终通知-----------------"); 
5. } 
6.  
7@AfterThrowing("anyMethod()"
8public void doAfterThrowing() 
9.  { 
10.   System.out.println("----------------执行意外通知-----------------"); 
11.  } 
12.   
13.@Around("anyMethod()"
14.public Object doAround(ProceedingJoinPoint pjp) throws Throwable 
15. { 
16.  System.out.println("----------------进入判断方法-----------------"); 
17.  Object result=pjp.proceed();  //该方法必须被执行 
18.  System.out.println("----------------退出判断方法-----------------"); 
19return result; 
20. } 
  
  
  
 我们把切面交给spring管理,要交给spring管理我们可以在配置文件同进行bean配置,或者使用扫描的方式。
  
 
 
Xml代码 
1.<bean id="interceptor" class="com.szy.spring.Interceptor"/> 
  
 下面我们进行测试
  
 
 
Java代码 
1.ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); 
2.        UserManager manager=(UserManager)context.getBean("userManager"); 
3.        manager.addUser("coolszy","kuka"); 
  
  
  
按照我们的设计,输入的结果应为
  
----------------执行前置通知-----------------
----------------进入判断方法-----------------
--------UserManagerImpl.addUser()----------
----------------执行后置通知-----------------
----------------执行最终通知-----------------
----------------退出判断方法-----------------
 
 
 
 
 
 
Spring学习笔记(16)----使用Spring配置文件实现AOP
----------------------------------------------
 
前面介绍了使用注解的方式,下面介绍使用配置文件的方式实现AOP。
  
使用配置方式,Interceptor类中不包含任何注解。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.import org.aspectj.lang.ProceedingJoinPoint; 
4
5.public class Interceptor 
6.{ 
7.   public void doBefore() 
8.    { 
9.        System.out.println("----------------执行前置通知-----------------"); 
10.    } 
11.     
12.   public void doAfterReturning() 
13.    { 
14.        System.out.println("----------------执行后置通知-----------------"); 
15.    } 
16.     
17.   public void doAfter() 
18.    { 
19.        System.out.println("----------------执行最终通知-----------------"); 
20.    } 
21.     
22.   public void doAfterThrowing() 
23.    { 
24.        System.out.println("----------------执行意外通知-----------------"); 
25.    } 
26.     
27.   public Object doAround(ProceedingJoinPoint pjp) throws Throwable 
28.    { 
29.        System.out.println("----------------进入判断方法-----------------"); 
30.        Object result=pjp.proceed();  //该方法必须被执行 
31.        System.out.println("----------------退出判断方法-----------------"); 
32.       return result; 
33.    } 
34.} 
  
 紧着这我们在配置文件中配置切面、切入点、通知等:
  
 
 
Xml代码 
1.<bean id="aspetbean" class="com.szy.spring.Interceptor"/> 
2.    <aop:config> 
3.        <aop:aspect id="aspet" ref="aspetbean"
4.            <aop:pointcut id="cut" expression="execution (* com.szy.spring.UserManagerImpl.*(..))"/> 
5.            <aop:before pointcut-ref="cut" method="doBefore"/> 
6.            <aop:after-returning pointcut-ref="cut" method="doAfterReturning"/> 
7.            <aop:after pointcut-ref="cut" method="doAfter"/> 
8.            <aop:after-throwing pointcut-ref="cut" method="doAfterThrowing"/> 
9.            <aop:around pointcut-ref="cut" method="doAround"/> 
10.        </aop:aspect> 
11.    </aop:config> 
  
 运行测试代码输入正常结果。
  
在实际开发中AOP一般用于权限设置等。
  
  
 
 
 
 
Spring学习笔记(17)----使用Spring注解方式管理事务
--------------------------------------------------
使用Spring+JDBC集成步骤如下:
  
 *配置数据源,例如:
  
 
 
Xml代码 
1.<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
2.            <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
3.            <property name="url" value="jdbc:mysql://localhost:3306/test"/> 
4.            <property name="username" value="root"/> 
5.            <property name="password" value="123456"/> 
6.            <!-- 连接池启动时的初始值 --> 
7.            <property name="initialSize" value="1"/> 
8.            <!-- 连接池的最大值 --> 
9.            <property name="maxActive" value="100"/> 
10.            <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --> 
11.            <property name="maxIdle" value="2"/> 
12.            <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --> 
13.            <property name="minIdle" value="1"/> 
14.        </bean> 
  
 *配置事务,配置事务时,需要在xml配置文件中引入用于声明事务的tx命名空间,事务的配置有两种方式:注解方式和基于XML配置的方式
  
  
  
下面演示下使用Spring注解方式管理事务
  
首先在配置文件中配置Spring提供的事务管理器
  
 
 
Xml代码 
1.<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
2.            <!-- 指定数据源 --> 
3.            <property name="dataSource" ref="dataSource"/> 
4.        </bean> 
  
 由于会使用注解方式,因此我们要打开注解处理器,对注解进行解析
  
 
 
Xml代码 
1.<tx:annotation-driven transaction-manager="txManager"/> 
  
  
  
这样我们的配置文件配置完成,下面我们在Mysql中建立一张表,
  
 
 
Sql代码 
1.create table users 
2.(                    
3. id int(11) not null auto_increment,   
4. username varchar(20) not null,        
5. primary key (id)                    
6.)  
  
  
  
根据数据库,我们创建javabean
  
 
 
Java代码 
1.package com.szy.spring.bean; 
2./**
3. * @author  coolszy
4. * @time    Dec 6, 2009 2:13:33 PM
5. */ 
6.public class User 
7.{ 
8.   private int id; 
9.   private String username; 
10.   public int getId() 
11.    { 
12.       return id; 
13.    } 
14.   public void setId(int id) 
15.    { 
16.       this.id = id; 
17.    } 
18.   public String getUsername() 
19.    { 
20.       return username; 
21.    } 
22.   public void setUsername(String username) 
23.    { 
24.       this.username = username; 
25.    } 
26.}    
  
  
  
然后创建DAO接口,在DAO中提供几个方法:
  
 
 
Java代码 
1.package com.szy.spring.dao; 
2
3.import java.util.List; 
4
5.import com.szy.spring.bean.User; 
6
7.public interface UserDAO 
8.{ 
9.   public void save(User user); 
10.   public void update(User user); 
11.    Public User  getUser(int id); 
12.   public void delete(int id); 
13.   public List<User> getAllUsers(); 
14.}    
  
  
  
实现这个接口
  
  
  
 
 
Java代码 
1.package com.szy.spring.dao.impl; 
2
3.import java.util.List; 
4
5.import com.szy.spring.bean.User; 
6.import com.szy.spring.service.UserService; 
7
8./**
9. * @author  coolszy
10. * @time    Dec 6, 2009 2:19:22 PM
11. */ 
12.public class UserDAOImplimplements UserDAO 
13.{ 
14
15.   public void delete(int id) 
16.    { 
17
18.    } 
19
20.   public List<User> getAllUsers() 
21.    { 
22.       return null
23.    } 
24
25.   public User getUser(int id) 
26.    { 
27
28.    } 
29
30.   public void save(User user) 
31.    { 
32
33.    } 
34
35.   public void update(User user) 
36.    { 
37
38.    } 
39
40.}    
  
  
  
下面把这个类交给Spring管理
  
 
 
Xml代码 
1.<bean id="userDAO" class="com.szy.spring.dao.impl.UserDAOImpl"/>   
  
 由于要通过数据源对表进行操作,因此在DAO中添加数据源。
  
 
 
Java代码 
1.private DataSource dataSource; 
2
3.   public void setDataSource(DataSource dataSource) 
4.    { 
5.       this.dataSource = dataSource; 
6.    }    
  
  
  
然后在配置文件中进行配置
  
 
 
Xml代码 
1.<bean id="userDAO" class="com.szy.spring.service.impl.UserDAOImpl"
2.            <property name="dataSource" ref="dataSource"/> 
3.        </bean>    
  
  
  
这样我们就把数据源注入到类中。
  
在UserDAOImpl类中我们提供了dataSource,这样我们就可以对数据库进行操作,但是不推荐直接使用dataSource,建议使用JdbcTemplate
  
 
 
Java代码 
1.private JdbcTemplate jdbcTemplate; 
2.   public void setDataSource(DataSource dataSource) 
3.    { 
4.       //this.dataSource = dataSource; 
5.       this.jdbcTemplate=new JdbcTemplate(dataSource); 
6.    }    
  
 下面我们使用jdbcTemplate对数据库进行增删改查,详细代码见附件。
  
 
 
Java代码 
1.package com.szy.spring.dao.impl; 
2
3.import java.util.List; 
4
5.import javax.sql.DataSource; 
6
7.import org.springframework.jdbc.core.JdbcTemplate; 
8
9.import com.szy.spring.bean.User; 
10.import com.szy.spring.dao.UserDAO; 
11
12./**
13. * @author  coolszy
14. * @time    Dec 6, 2009 2:19:22 PM
15. */ 
16.public class UserDAOImplimplements UserDAO 
17.{ 
18.   //private DataSource dataSource; 
19.   private JdbcTemplate jdbcTemplate; 
20.   public void setDataSource(DataSource dataSource) 
21.    { 
22.       //this.dataSource = dataSource; 
23.       this.jdbcTemplate=new JdbcTemplate(dataSource); 
24.    } 
25
26.   public void delete(int id) 
27.    { 
28.        jdbcTemplate.update("delete from users where id=?",new Object[]{id}, 
29.               new int[]{java.sql.Types.INTEGER}); 
30.    } 
31
32.   public List<User> getAllUsers() 
33.    { 
34.       return (List<User>)jdbcTemplate.query("select * from users",new UserRowMapper()); 
35.    } 
36
37.   public User getUser(int id) 
38.    { 
39.       return (User)jdbcTemplate.queryForObject("select * from users where id=?",new Object[]{id},  
40.               new int[]{java.sql.Types.INTEGER},new UserRowMapper()); 
41
42.    } 
43
44.   public void save(User user) 
45.    {  
46.        jdbcTemplate.update("insert into users(username) values(?)",new Object[]{user.getUsername()}, 
47.               new int[]{java.sql.Types.VARCHAR}); 
48
49.    } 
50
51.   public void update(User user) 
52.    { 
53.        jdbcTemplate.update("update users set username=? where id=?",new Object[]{user.getUsername(),user.getId()}, 
54.               new int[]{java.sql.Types.VARCHAR, java.sql.Types.INTEGER}); 
55
56.    } 
57
58.}    
  
 编写测试代码,代码运行正常。
  
在我们实现的每个方法中如delete()方法,如果delete方法是这样
  
 
 
Java代码 
1.public void delete(int id) 
2.    { 
3.        jdbcTemplate.update("delete from users where id=?",new Object[]{id}, 
4.               new int[]{java.sql.Types.INTEGER}); 
5.jdbcTemplate.update("delete from users where id=?",new Object[]{id}, 
6.               new int[]{java.sql.Types.INTEGER}); 
7
8.    } 
9.     
  
 这样每条语句都会在各自的事务中执行,并不能保证在同一使用中执行,为了保证在同一事务中执行,我们应使用Spring容器提供的声明事务,我们在UserDAOImpl 类上加入@Transactional,表示该类受Spring事务管理。如果该类中每个方法不需要事务管理,如getUser方法,则在该方法前加入
  
 
 
Java代码 
1.@Transactional(propagation=Propagation.NOT_SUPPORTED) 
  
  
  
  
  
PS:在上面的配置文件中我们在配置文件中指明了驱动类等信息,如果我们想写在配置文件中要怎么配置能,首先我们编写配置文件,
  
 
 
Jdbc.properties代码 
1.driverClassName=com.mysql.jdbc.Driver 
2.url=jdbc\:mysql\://localhost\:3306/test 
3.username=root 
4.password=123456 
5.initialSize=1 
6.maxActive=100 
7.maxIdle=2 
8.minIdle=1    
  
 然后Spring的配置文件需进行如下配置:
  
 
 
Xml代码 
1.<context:property-placeholder location="classpath:jdbc.properties"/> 
2.        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
3.            <property name="driverClassName" value="${driverClassName}"/> 
4.            <property name="url" value="${url}"/> 
5.            <property name="username" value="${username}"/> 
6.            <property name="password" value="${password}"/> 
7.            <property name="initialSize" value="${initialSize}"/> 
8.            <property name="maxActive" value="${maxActive}"/> 
9.            <property name="maxIdle" value="${maxIdle}"/> 
10.            <property name="minIdle" value="${minIdle}"/> 
11.        </bean>    
  
  这样就可以从属性文件中读取到配置信息。
  
  
 
 
 
 
 
Spring学习笔记(18)----使用Spring配置文件实现事务管理
-------------------------------------------------------
由于我们要拦截UserDAOImpl中的方法,因此我们需要在配置文件中配置信息,在配置文件中使用了AOP技术来拦截方法。
  
 
 
Xml代码 
1.<aop:config> 
2.    <aop:pointcut id="transactionPointcut" expression="execution(* com.szy.spring.dao.impl..*.*(..))"/> 
3.    <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/> 
4.  </aop:config>  
5.  <tx:advice id="txAdvice" transaction-manager="txManager"
6.     <tx:attributes> 
7.      <!-- 如果连接的方法是以get开头的方法,则不使用事务 --> 
8.       <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> 
9.       <tx:method name="*"/> 
10.     </tx:attributes> 
11.  </tx:advice> 
  
   
  
这样Spring就能对这个类进行事务管理。
  
  
  
下面我们测试下数据库操作是否在同一事务中执行。
  
假设我们的delete方法如下:
  
 
 
Java代码 
1.public void delete(int id) 
2. { 
3.  jdbcTemplate.update("delete from users where id=?",new Object[]{id}, 
4.   new int[]{java.sql.Types.INTEGER}); 
5.  jdbcTemplate.update("delete from users1 where id=10"); 
6. } 
  
  
  
  
  
在第二条删除语句中,users1表是不存在的,如果两次update语句是在两个事务中执行,则第一条能成功执行,并且数据库中该id的记录已经被删除,而第二条由于不存在该表不能正常删除。如果在同一事务中执行,由于第二条update出错,数据库中不能删除任何记录。
  
测试代码:
  
 
 
Java代码 
1.@Test 
2.public void testDelete() 
3. { 
4.  userDAO.delete(5); 
5. } 
  
  
 程序报错,同时id=5的记录没有被删除。如果我们把配置文件中关于事务配置的信息给注释掉,再次测试,程序同样报错,但是id=5的记录被成功删除掉,这说明这两条update语句是在两个不同的事务中运行。
  
  
  
PS:在平时开发中,Spring团队建议使用注解的方式进行配置,这样配置文件显得精简,同时也会做到精确控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值