1.1 AOP概述

1.1.1什么是AOP

  • AOP(Aspect Oriented Programing) 面向切面编程。
  • AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)。

  • Spring的AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码。
  • AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译的时候提供横向代码的织入。

1.1.2AOP底层原理

  • 代理机制

    • 动态代理(JDK的动态代理)

      • JDK的动态代理,对实现了接口的类生成代理。  

1.1.3Spring的AOP代理

  • JDK动态代理:对实现了接口的类生成代理
  • CGLIB代理机制:对类生成代理  

1.1.4AOP的术语

  • joinpoint(连接点):所谓的连接点是指那些被拦截到的点。在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点。
  • pointcut(切入点):所谓的切入点是指我们要对那些joinpoint进行拦截的定义。
  • Advice(通知/增强):所谓通知是指拦截到joinpoint之后所要做的事情就是通知。通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)。
  • Introduction(引介):引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或属性。
  • Target(目标对象):代理的目标对象。
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。Spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入。
  • Proxy(代理):一个雷被AOP织入增强后,就产生了一个结果代理类。
  • Aspect(切面):是切入点和通知(引介)的结合。

1.2 AOP底层实现 

1.2.1JDK的动态代理

  1. package cn.demo4;
  2.  
  3. public interface IUserDAO {
  4. public void add();
  5. public void update();
  6. public void delete();
  7. public void find();
  8. }
  1. package cn.demo4;
  2.  
  3. public class UserDAOImpl implements IUserDAO {
  4.  
  5. @Override
  6. public void add() {
  7. System.out.println("添加用户");
  8. }
  9.  
  10. @Override
  11. public void update() {
  12. System.out.println("修改用户");
  13. }
  14.  
  15. @Override
  16. public void delete() {
  17. System.out.println("删除用户");
  18. }
  19.  
  20. @Override
  21. public void find() {
  22. System.out.println("查询用户");
  23. }
  24.  
  25. }
  1. package cn.demo4;
  2.  
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Proxy;
  6.  
  7. public class UserDAOProxy implements InvocationHandler {
  8.  
  9. private IUserDAO iUserDAO;
  10. public UserDAOProxy(IUserDAO iUserDAO){
  11. this.iUserDAO = iUserDAO;
  12. }
  13.  
  14. public IUserDAO getProxy(){
  15. Object result = Proxy.newProxyInstance(iUserDAO.getClass().getClassLoader(), iUserDAO.getClass().getInterfaces(),this );
  16. return (IUserDAO) result;
  17. }
  18.  
  19. @Override
  20. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  21. if(method.getName().equals("add")){
  22. System.out.println("日志记录");
  23. Object result = method.invoke(iUserDAO, args);
  24. System.out.println("日志记录");
  25. return result;
  26. }
  27. if(method.getName().equals("delete")){
  28. System.out.println("日志记录");
  29. Object result = method.invoke(iUserDAO, args);
  30. System.out.println("日志记录");
  31. return result;
  32. }
  33. return method.invoke(iUserDAO, args);
  34. }
  35.  
  36. }
  1. package cn.demo4;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class TestDemo {
  6. @Test
  7. public void demo1(){
  8. IUserDAO iUserDAO = new UserDAOImpl();
  9. IUserDAO proxy = new UserDAOProxy(iUserDAO).getProxy();
  10. proxy.add();
  11. proxy.delete();
  12. proxy.find();
  13. proxy.update();
  14. }
  15. }

1.2.2CGLIB动态代理

  1. package cn.demo5;
  2.  
  3. public class ProductDAO {
  4.  
  5. public void add(){
  6. System.out.println("添加商品");
  7. }
  8.  
  9. public void delete(){
  10. System.out.println("删除商品");
  11. }
  12.  
  13. public void update(){
  14. System.out.println("修改商品");
  15. }
  16. public void find(){
  17. System.out.println("查询商品");
  18. }
  19.  
  20. }
  1. package cn.demo5;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.cglib.proxy.Enhancer;
  6. import org.springframework.cglib.proxy.MethodInterceptor;
  7. import org.springframework.cglib.proxy.MethodProxy;
  8.  
  9. public class ProductDAOProxy implements MethodInterceptor{
  10. private ProductDAO productDAO;
  11. public ProductDAOProxy(ProductDAO productDAO){
  12. this.productDAO = productDAO;
  13. }
  14.  
  15. public ProductDAO getProxy(){
  16. //创建CGLIB的核心类
  17. Enhancer enhancer = new Enhancer();
  18. //为其设置父类
  19. enhancer.setSuperclass(productDAO.getClass());
  20. //设置回调
  21. enhancer.setCallback(this);
  22. //创建代理
  23. return (ProductDAO) enhancer.create();
  24. }
  25.  
  26. @Override
  27. public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  28. if(method.getName().equals("add")){
  29. System.out.println("日志记录");
  30. return methodProxy.invokeSuper(proxy, args);
  31. }
  32. if(method.getName().equals("delete")){
  33. System.out.println("日志记录");
  34. return methodProxy.invokeSuper(proxy, args);
  35. }
  36. return methodProxy.invokeSuper(proxy, args);
  37. }
  38. }
  1. package cn.demo5;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class TestDemo {
  6. @Test
  7. public void demo1(){
  8. ProductDAO proxy = new ProductDAOProxy(new ProductDAO()).getProxy();
  9. proxy.add();
  10. proxy.delete();
  11. proxy.find();
  12. proxy.update();
  13. }
  14. }

 1.3 Spring中的AOP

1.3.1Spring的传统AOP

  • AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice。
  • Spring按照通知Advice在目标类方法的连接点位置,可以分为
    • 前置通知org.springframework.aop.MethodBeforeAdvice

      • 在目标方法执行前实施增强
    • 后置通知org.springframework.aop.AfterReturningAdvice
      • 在目标方法执行后实施增强
    • 环绕通知org.aopalliance.intercept.MethodInterceptor
      • 在目标方法执行前后实施增强
    • 异常抛出通知org.springframework.aop.ThrowsAdvice
      • 在方法抛出异常后实施增强
    • 引介通知org.springframework.aop.IntroductionInterceptor
      • 在目标类中添加一些新的方法和属性

  
1.3.2Spring中的切面类型

  • Advisor:Spring中传统切面。

    • Advisor:都是一个切点和一个通知组合。
    • Aspect:多个切点和多个通知的组合。
  • Advisor:代表一般切面。Advisor本身就是一个切面,对目标类所有哦方法进行拦截。(不带有切点的切面,针对所有方法进行拦截)
  • PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类那些方法(带有切点的切面,针对某个方法进行拦截)
  • IntroductionAdvisor:代表引介切面,针对引介通知而使用切面。  

1.3.3Spring的AOP的开发--针对所有方法的增强(不带切点的切面)

  • 导入相应的jar包

    • spring-aop-3.2.0.RELEASE.jar
    • com.springsource.org.aopalliance-1.0.0.jar
  • 编写被代理的接口和实现类
  1. package cn.demo6;
  2.  
  3. public interface ICustomerDAO {
  4. public void add();
  5. public void delete();
  6. public void update();
  7. public void find();
  8. }
  1. package cn.demo6;
  2.  
  3. public class CustomerDAOImpl implements ICustomerDAO {
  4.  
  5. @Override
  6. public void add() {
  7. System.out.println("添加用户");
  8.  
  9. }
  10.  
  11. @Override
  12. public void delete() {
  13. System.out.println("删除用户");
  14.  
  15. }
  16.  
  17. @Override
  18. public void update() {
  19. System.out.println("修改用户");
  20.  
  21. }
  22.  
  23. @Override
  24. public void find() {
  25. System.out.println("查询用户");
  26.  
  27. }
  28.  
  29. }
  • 编写增强的代码
  1. package cn.demo6;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.aop.MethodBeforeAdvice;
  6.  
  7. public class MyBeforeAdvice implements MethodBeforeAdvice {
  8. /**
  9. * @param method 执行的方法
  10. * @param args 参数
  11. * @param target 目标对象
  12. */
  13. @Override
  14. public void before(Method method, Object[] args, Object target) throws Throwable {
  15. System.out.println("前置增强");
  16. }
  17.  
  18. }
  • 生成代理(配置生成代理)

    • Spring基于ProxyFactoryBean类,底层自动选择使用JDK的动态代理还是CGLIB的代理。
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
  8. <!-- 定义目标对象 -->
  9. <bean id="customerDAO" class="cn.demo6.CustomerDAOImpl"></bean>
  10. <!-- 定义增强 -->
  11. <bean id="beforeAdvice" class="cn.demo6.MyBeforeAdvice"></bean>
  12.  
  13. <!-- 生成代理 -->
  14. <!-- Spring支持配置生成代理 -->
  15. <bean id="customerDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
  16. <!-- 设置目标对象 -->
  17. <property name="target" ref="customerDAO"/>
  18. <!-- 设置实现接口 value接口的全路径-->
  19. <property name="proxyInterfaces" value="cn.demo6.ICustomerDAO" />
  20. <!-- 拦截的名称 -->
  21. <property name="interceptorNames" value="beforeAdvice"/>
  22.  
  23. </bean>
  24.  
  25. </beans>
  • 测试
  1. package cn.demo6;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("customerDAOProxy")
  15. private ICustomerDAO customerDAO;
  16. @Test
  17. public void demo1(){
  18. customerDAO.add();
  19. customerDAO.delete();
  20. customerDAO.update();
  21. customerDAO.find();
  22. }
  23.  
  24. }

1.3.4Spring的AOP的开发--针对某些方法的增强(带有切点的切面)  

  • 创建被代理对象
  1. package cn.demo7;
  2.  
  3. public class OrderDAO {
  4. public void add(){
  5. System.out.println("增加");
  6. }
  7. public void delete(){
  8. System.out.println("删除");
  9. }
  10. public void find(){
  11. System.out.println("查询");
  12. }
  13. public void update(){
  14. System.out.println("修改");
  15. }
  16. }
  • 编写要增强的类
  1. package cn.demo7;
  2.  
  3. import org.aopalliance.intercept.MethodInterceptor;
  4. import org.aopalliance.intercept.MethodInvocation;
  5.  
  6. public class MyAroundAdvice implements MethodInterceptor{
  7.  
  8. @Override
  9. public Object invoke(MethodInvocation invocation) throws Throwable {
  10. System.out.println("方法执行前--日志记录");
  11. Object result = invocation.proceed();
  12. System.out.println("方法执行后--日志记录");
  13. return result;
  14. }
  15.  
  16. }
  • 生成代理
  1. <!-- 定义切点切面 -->
  2. <bean id="pointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  3. <!-- 定义表达式来规定哪些方法执行拦截 -->
  4. <property name="pattern" value="cn.demo7.OrderDAO.add.*"/>
  5. <!-- 应用增强 -->
  6. <property name="advice" ref="aroundAdvice"/>
  7. </bean>
  8.  
  9. <!-- 定义目标对象 -->
  10. <bean id="orderDAO" class="cn.demo7.OrderDAO"></bean>
  11. <!-- 定义增强 -->
  12. <bean id="aroundAdvice" class="cn.demo7.MyAroundAdvice"/>
  13. <!-- 定义生成的代理对象 -->
  14. <bean id="orderDAOProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
  15. <!-- 配置目标 -->
  16. <property name="target" ref="orderDAO"></property>
  17. <!-- 针对类的代理 -->
  18. <property name="proxyTargetClass" value="true"/>
  19. <!-- 在目标上应用增强 -->
  20. <property name="interceptorNames" value="pointcutAdvisor"/>
  21. </bean>
  • 测试类
  1. package cn.demo7;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("orderDAOProxy")
  15. private OrderDAO orderDAO;
  16. @Test
  17. public void demo1(){
  18. orderDAO.add();
  19. orderDAO.delete();
  20. orderDAO.find();
  21. orderDAO.update();
  22. }
  23.  
  24. }

1.3.5自动代理

  • 前面的案例中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大。
  • 自动创建代理:-----基于后处理Bean,在Bean创建的过程中完成的增强。生成的Bean就是代理。
    • BeanNameAutoProxyCreator根据Bean名称创建
  1. package cn.demo6;
  2.  
  3. public interface ICustomerDAO {
  4. public void add();
  5. public void delete();
  6. public void update();
  7. public void find();
  8. }
  1. package cn.demo6;
  2.  
  3. public class CustomerDAOImpl implements ICustomerDAO {
  4.  
  5. @Override
  6. public void add() {
  7. System.out.println("添加用户");
  8.  
  9. }
  10.  
  11. @Override
  12. public void delete() {
  13. System.out.println("删除用户");
  14.  
  15. }
  16.  
  17. @Override
  18. public void update() {
  19. System.out.println("修改用户");
  20.  
  21. }
  22.  
  23. @Override
  24. public void find() {
  25. System.out.println("查询用户");
  26.  
  27. }
  28.  
  29. }
  1. package cn.demo6;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.aop.MethodBeforeAdvice;
  6.  
  7. public class MyBeforeAdvice implements MethodBeforeAdvice {
  8. /**
  9. * @param method 执行的方法
  10. * @param args 参数
  11. * @param target 目标对象
  12. */
  13. @Override
  14. public void before(Method method, Object[] args, Object target) throws Throwable {
  15. System.out.println("前置增强");
  16. }
  17.  
  18. }
  1. package cn.demo7;
  2.  
  3. public class OrderDAO {
  4. public void add(){
  5. System.out.println("增加");
  6. }
  7. public void delete(){
  8. System.out.println("删除");
  9. }
  10. public void find(){
  11. System.out.println("查询");
  12. }
  13. public void update(){
  14. System.out.println("修改");
  15. }
  16. }
  1. package cn.demo7;
  2.  
  3. import org.aopalliance.intercept.MethodInterceptor;
  4. import org.aopalliance.intercept.MethodInvocation;
  5.  
  6. public class MyAroundAdvice implements MethodInterceptor{
  7.  
  8. @Override
  9. public Object invoke(MethodInvocation invocation) throws Throwable {
  10. System.out.println("方法执行前--日志记录");
  11. Object result = invocation.proceed();
  12. System.out.println("方法执行后--日志记录");
  13. return result;
  14. }
  15.  
  16. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
  8. <!-- 定义目标对象 -->
  9. <bean id="customerDAO" class="cn.demo6.CustomerDAOImpl"></bean>
  10. <!-- 定义增强 -->
  11. <bean id="beforeAdvice" class="cn.demo6.MyBeforeAdvice"></bean>
  12.  
  13. <!-- 定义目标对象 -->
  14. <bean id="orderDAO" class="cn.demo7.OrderDAO"></bean>
  15. <!-- 定义增强 -->
  16. <bean id="aroundAdvice" class="cn.demo7.MyAroundAdvice"/>
  17.  
  18. <!-- 自动代理:按名称的代理 基于后处理Bean,后处理Bea不需要配置id -->
  19. <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
  20. <property name="beanNames" value="*DAO"/>
  21. <property name="interceptorNames" value="beforeAdvice"/>
  22. </bean>
  23.  
  24. </beans>
  1. package cn.demo8;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. import cn.demo6.ICustomerDAO;
  11. import cn.demo7.OrderDAO;
  12.  
  13. @RunWith(SpringJUnit4ClassRunner.class)
  14. @ContextConfiguration("classpath:applicationContext2.xml")
  15. public class SpringTest {
  16. @Autowired
  17. @Qualifier("customerDAO")
  18. private ICustomerDAO customerDAO;
  19. @Autowired
  20. @Qualifier("orderDAO")
  21. private OrderDAO orderDAO;
  22.  
  23. @Test
  24. public void demo1(){
  25. orderDAO.add();
  26. orderDAO.delete();
  27.  
  28. customerDAO.add();
  29. customerDAO.delete();
  30.  
  31. }
  32.  
  33. }
    • DefaultAdvisorAutoProxyCreator根据Advisor本身包含信息创建代理
  1. package cn.demo6;
  2.  
  3. public interface ICustomerDAO {
  4. public void add();
  5. public void delete();
  6. public void update();
  7. public void find();
  8. }
  1. package cn.demo6;
  2.  
  3. public class CustomerDAOImpl implements ICustomerDAO {
  4.  
  5. @Override
  6. public void add() {
  7. System.out.println("添加用户");
  8.  
  9. }
  10.  
  11. @Override
  12. public void delete() {
  13. System.out.println("删除用户");
  14.  
  15. }
  16.  
  17. @Override
  18. public void update() {
  19. System.out.println("修改用户");
  20.  
  21. }
  22.  
  23. @Override
  24. public void find() {
  25. System.out.println("查询用户");
  26.  
  27. }
  28.  
  29. }
  1. package cn.demo6;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import org.springframework.aop.MethodBeforeAdvice;
  6.  
  7. public class MyBeforeAdvice implements MethodBeforeAdvice {
  8. /**
  9. * @param method 执行的方法
  10. * @param args 参数
  11. * @param target 目标对象
  12. */
  13. @Override
  14. public void before(Method method, Object[] args, Object target) throws Throwable {
  15. System.out.println("前置增强");
  16. }
  17.  
  18. }
  1. package cn.demo7;
  2.  
  3. public class OrderDAO {
  4. public void add(){
  5. System.out.println("增加");
  6. }
  7. public void delete(){
  8. System.out.println("删除");
  9. }
  10. public void find(){
  11. System.out.println("查询");
  12. }
  13. public void update(){
  14. System.out.println("修改");
  15. }
  16. }
  1. package cn.demo7;
  2.  
  3. import org.aopalliance.intercept.MethodInterceptor;
  4. import org.aopalliance.intercept.MethodInvocation;
  5.  
  6. public class MyAroundAdvice implements MethodInterceptor{
  7.  
  8. @Override
  9. public Object invoke(MethodInvocation invocation) throws Throwable {
  10. System.out.println("方法执行前--日志记录");
  11. Object result = invocation.proceed();
  12. System.out.println("方法执行后--日志记录");
  13. return result;
  14. }
  15.  
  16. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
  8. <!-- 定义目标对象 -->
  9. <bean id="customerDAO" class="cn.demo6.CustomerDAOImpl"></bean>
  10. <!-- 定义增强 -->
  11. <bean id="beforeAdvice" class="cn.demo6.MyBeforeAdvice"></bean>
  12.  
  13. <!-- 定义目标对象 -->
  14. <bean id="orderDAO" class="cn.demo7.OrderDAO"></bean>
  15. <!-- 定义增强 -->
  16. <bean id="aroundAdvice" class="cn.demo7.MyAroundAdvice"/>
  17.  
  18. <!-- 定义一个带有切点的切面 -->
  19. <bean id="pointcut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  20. <property name="pattern" value=".*add.*"/>
  21. <property name="advice" ref="aroundAdvice"/>
  22. </bean>
  23.  
  24. <!-- 自动生成代理 -->
  25. <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
  26.  
  27. </bean>
  28.  
  29. </beans>
  1. package cn.demo9;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. import cn.demo6.ICustomerDAO;
  11. import cn.demo7.OrderDAO;
  12.  
  13. @RunWith(SpringJUnit4ClassRunner.class)
  14. @ContextConfiguration("classpath:applicationContext3.xml")
  15. public class SpringTest {
  16. @Autowired
  17. @Qualifier("customerDAO")
  18. private ICustomerDAO customerDAO;
  19. @Autowired
  20. @Qualifier("orderDAO")
  21. private OrderDAO orderDAO;
  22.  
  23. @Test
  24. public void demo1(){
  25. orderDAO.add();
  26. orderDAO.delete();
  27.  
  28. customerDAO.add();
  29. customerDAO.delete();
  30.  
  31. }
  32.  
  33. }
    • AnnotationAwareAspectAutoProxyCreator基于Bean中的AspectJ注解进行自动代理。

区分基于ProxyFactoryBean的代理与自动代理的区别?

  • ProxyFactoryBean是先有被代理的对象,将被代理的对象传入代理类中生成代理。
  • 自动代理是基于后处理Bean,在Bean生成过程中产生了代理对象,把代理对象返回,生成的Bean已经是代理对象了。

  

1.4 Spring的AspectJ的AOP  

1.4.1AspectJ简介

  • AspectJ是一个基于Java语言的AOP框架。
  • Spring2.0以后新增了对AspectJ切点表达式支持。
  • @AspectJ是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面。
  • 新版本的Spring框架,建议使用AspectJ方式来开发AOP。

      

1.4.2AspectJ表达式

  • 语法:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
  • 例如:(*在正则表达式中表示任意多次,0,1或多次;.表示任意字符)

    • execution(public * *(..)) 匹配所有类public方法
    • execution(* cn.spring3.demo1.dao.*(..)) 匹配cn.spring3.demo1.dao包下的所有方法
    • execution(*  cn.spring3.demo1.dao..*(..)) 匹配cn.spring3.demo1.dao包及子包的所有方法
    • execution(* cn.spring3.demo1.dao.GenericDAO+.*(..))  匹配GenericDAO
    • execution(* save(..)) 匹配所有save开头的方法

1.4.3AspectJ提供不同的通知类型

  • @Before 前置通知
  • @AfterReturning 后置通知
  • @Around 环绕通知
  • @AfterThrowing 抛出通知
  • @After 最终通知,不管是否异常,该通知都会执行
  • @DeclareParents引介通知

1.4.4基于注解

  • 引入相应的jar包

    • spring-aop-3.2.0.RELEASE.jar
    • com.springsource.org.aopalliance-1.0.0.jar
    • spring-aspects-3.2.0.RELEASE.jar
    • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
  • 编写被增强类(目标类)
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public void find(){
  14. System.out.println("查询用户");
  15. }
  16. }
  • 使用AspectJ注解形式
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.aspectj.lang.annotation.Before;
  5.  
  6. /**
  7. * 切面类:就是切点与增强的结合
  8. * @author love
  9. *
  10. */
  11. @Aspect
  12. public class MyAspect {
  13.  
  14. @Before("execution(* cn.demo1.UserDAO.*(..))")
  15. public void before(){
  16. System.out.println("前置增强。。。。");
  17. }
  18.  
  19. }
  • 创建applicationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  • 测试类
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }

1.4.4AspectJ通知类型

  • @Before 前置通知,在方法之前执行,没有办法阻止目标方法执行。
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public void find(){
  14. System.out.println("查询用户");
  15. }
  16. }
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Before;
  6.  
  7. /**
  8. * 切面类:就是切点与增强的结合
  9. * @author love
  10. *
  11. */
  12. @Aspect
  13. public class MyAspect {
  14.  
  15. @Before("execution(* cn.demo1.UserDAO.add(..))")
  16. public void before(JoinPoint joinPoint){
  17. System.out.println("前置增强。。。。"+joinPoint);
  18. }
  19.  
  20. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }
  • @AfterReturning 后置通知,获取方法的返回值。 
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public int find(){
  14. System.out.println("查询用户");
  15. return 1;
  16. }
  17. }
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.AfterReturning;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Before;
  7.  
  8. /**
  9. * 切面类:就是切点与增强的结合
  10. * @author love
  11. *
  12. */
  13. @Aspect
  14. public class MyAspect {
  15.  
  16. @Before("execution(* cn.demo1.UserDAO.add(..))")
  17. public void before(JoinPoint joinPoint){
  18. System.out.println("前置增强。。。。"+joinPoint);
  19. }
  20. @AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
  21. public void afterReturning(Object returnVal){
  22. System.out.println("后置增强。。。。"+returnVal);
  23. }
  24. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }
  • @Around 环绕通知,可以在方法之前和方法之后执行的,可以阻止目标方法的执行。
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public int find(){
  14. System.out.println("查询用户");
  15. return 1;
  16. }
  17. }
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.AfterReturning;
  6. import org.aspectj.lang.annotation.Around;
  7. import org.aspectj.lang.annotation.Aspect;
  8. import org.aspectj.lang.annotation.Before;
  9.  
  10. /**
  11. * 切面类:就是切点与增强的结合
  12. * @author love
  13. *
  14. */
  15. @Aspect
  16. public class MyAspect {
  17.  
  18. @Before("execution(* cn.demo1.UserDAO.add(..))")
  19. public void before(JoinPoint joinPoint){
  20. System.out.println("前置增强。。。。"+joinPoint);
  21. }
  22.  
  23. @AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
  24. public void afterReturning(Object returnVal){
  25. System.out.println("后置增强。。。。"+returnVal);
  26. }
  27. @Around(value="execution(* cn.demo1.UserDAO.update(..))")
  28. public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
  29. System.out.println("环绕前增强");
  30. Object obj = joinPoint.proceed();
  31. System.out.println("环绕后增强");
  32. return obj;
  33. }
  34. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }
  • AfterThrowing抛出异常通知
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public int find(){
  14. System.out.println("查询用户");
  15. int i = 1/0;
  16. return 1;
  17. }
  18. }
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.AfterReturning;
  6. import org.aspectj.lang.annotation.AfterThrowing;
  7. import org.aspectj.lang.annotation.Around;
  8. import org.aspectj.lang.annotation.Aspect;
  9. import org.aspectj.lang.annotation.Before;
  10.  
  11. /**
  12. * 切面类:就是切点与增强的结合
  13. * @author love
  14. *
  15. */
  16. @Aspect
  17. public class MyAspect {
  18.  
  19. @Before("execution(* cn.demo1.UserDAO.add(..))")
  20. public void before(JoinPoint joinPoint){
  21. System.out.println("前置增强。。。。"+joinPoint);
  22. }
  23.  
  24. @AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
  25. public void afterReturning(Object returnVal){
  26. System.out.println("后置增强。。。。"+returnVal);
  27. }
  28. @Around(value="execution(* cn.demo1.UserDAO.update(..))")
  29. public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
  30. System.out.println("环绕前增强");
  31. Object obj = joinPoint.proceed();
  32. System.out.println("环绕后增强");
  33. return obj;
  34. }
  35. @AfterThrowing(value="execution(* cn.demo1.UserDAO.find(..))",throwing="e")
  36. public void afterThrowing(Throwable e){
  37. System.out.println("出异常了。。。"+e.getMessage());
  38. }
  39.  
  40. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }
  • After 最终通知
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public int find(){
  14. System.out.println("查询用户");
  15. int i = 1/0;
  16. return 1;
  17. }
  18. }
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.After;
  6. import org.aspectj.lang.annotation.AfterReturning;
  7. import org.aspectj.lang.annotation.AfterThrowing;
  8. import org.aspectj.lang.annotation.Around;
  9. import org.aspectj.lang.annotation.Aspect;
  10. import org.aspectj.lang.annotation.Before;
  11.  
  12. /**
  13. * 切面类:就是切点与增强的结合
  14. * @author love
  15. *
  16. */
  17. @Aspect
  18. public class MyAspect {
  19.  
  20. @Before("execution(* cn.demo1.UserDAO.add(..))")
  21. public void before(JoinPoint joinPoint){
  22. System.out.println("前置增强。。。。"+joinPoint);
  23. }
  24.  
  25. @AfterReturning(value="execution(* cn.demo1.UserDAO.find(..))",returning="returnVal")
  26. public void afterReturning(Object returnVal){
  27. System.out.println("后置增强。。。。"+returnVal);
  28. }
  29. @Around(value="execution(* cn.demo1.UserDAO.update(..))")
  30. public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
  31. System.out.println("环绕前增强");
  32. Object obj = joinPoint.proceed();
  33. System.out.println("环绕后增强");
  34. return obj;
  35. }
  36. @AfterThrowing(value="execution(* cn.demo1.UserDAO.find(..))",throwing="e")
  37. public void afterThrowing(Throwable e){
  38. System.out.println("出异常了。。。"+e.getMessage());
  39. }
  40. @After(value="execution(* cn.demo1.UserDAO.find(..))")
  41. public void after(){
  42. System.out.println("最终通知");
  43. }
  44.  
  45. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }

1.4.5切点的注解

  • 在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用@Pointcut进行定义。
  • 切点方法:private void 无参方法,方法名为切点名。
  • 当多个切点时,可以使用||进行连接。
  1. package cn.demo1;
  2.  
  3. public class UserDAO {
  4. public void add(){
  5. System.out.println("添加用户");
  6. }
  7. public void update(){
  8. System.out.println("修改用户");
  9. }
  10. public void delete(){
  11. System.out.println("删除用户");
  12. }
  13. public int find(){
  14. System.out.println("查询用户");
  15. int i = 1/0;
  16. return 1;
  17. }
  18. }
  1. package cn.demo1;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.After;
  6. import org.aspectj.lang.annotation.AfterReturning;
  7. import org.aspectj.lang.annotation.AfterThrowing;
  8. import org.aspectj.lang.annotation.Around;
  9. import org.aspectj.lang.annotation.Aspect;
  10. import org.aspectj.lang.annotation.Before;
  11. import org.aspectj.lang.annotation.Pointcut;
  12.  
  13. /**
  14. * 切面类:就是切点与增强的结合
  15. * @author love
  16. *
  17. */
  18. @Aspect
  19. public class MyAspect {
  20.  
  21. @Before("execution(* cn.demo1.UserDAO.add(..))")
  22. public void before(JoinPoint joinPoint){
  23. System.out.println("前置增强。。。。"+joinPoint);
  24. }
  25.  
  26. @AfterReturning(value="MyAspect.pointcut()",returning="returnVal")
  27. public void afterReturning(Object returnVal){
  28. System.out.println("后置增强。。。。"+returnVal);
  29. }
  30. @Around(value="execution(* cn.demo1.UserDAO.update(..))")
  31. public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
  32. System.out.println("环绕前增强");
  33. Object obj = joinPoint.proceed();
  34. System.out.println("环绕后增强");
  35. return obj;
  36. }
  37. @AfterThrowing(value="MyAspect.pointcut()",throwing="e")
  38. public void afterThrowing(Throwable e){
  39. System.out.println("出异常了。。。"+e.getMessage());
  40. }
  41. @After("MyAspect.pointcut()")
  42. public void after(){
  43. System.out.println("最终通知");
  44. }
  45.  
  46. @Pointcut("execution(* cn.demo1.UserDAO.find(..))")
  47. private void pointcut(){}
  48.  
  49. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 开启自动生成代理 -->
  10. <aop:aspectj-autoproxy/>
  11.  
  12. <bean id="userDAO" class="cn.demo1.UserDAO"/>
  13.  
  14. <bean id="myAspect" class="cn.demo1.MyAspect"/>
  15.  
  16. </beans>
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. userDAO.add();
  20. userDAO.delete();
  21. userDAO.find();
  22. userDAO.update();
  23. }
  24.  
  25. }
  • Advisor和Aspect的区别?

    • Advisor:Spring传统意义上的切面,支持一个切点和一个通知的组合。
    • Aspect:支持多个切点和多个通知的组合。

1.4.6基于XML  

  • 定义被增强的类--目标类
  1. package cn.demo2;
  2.  
  3. public class ProductDAO {
  4. public void add(){
  5. System.out.println("添加商品");
  6. }
  7. public void update(){
  8. System.out.println("修改商品");
  9. }
  10. public void delete(){
  11. System.out.println("删除商品");
  12. }
  13. public void find(){
  14. System.out.println("查询商品");
  15. }
  16. }
  • 定义切面
  1. package cn.demo2;
  2. /**
  3. * 切面类
  4. */
  5. public class MyAspect {
  6.  
  7. public void before(){
  8. System.out.println("前置通知");
  9. }
  10.  
  11. }
  • applicationContext2.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  9. <!-- 定义被增强的类 -->
  10. <bean id="productDAO" class="cn.demo2.ProductDAO"/>
  11. <!-- 定义切面 -->
  12. <bean id="myAspect" class="cn.demo2.MyAspect"/>
  13.  
  14. <!-- 定义AOP的配置 -->
  15. <aop:config>
  16. <!-- 定义切点 -->
  17. <aop:pointcut expression="execution(* cn.demo2.ProductDAO.add(..))" id="pointcut"/>
  18. <aop:aspect ref="myAspect">
  19. <aop:before method="before" pointcut-ref="pointcut" />
  20. </aop:aspect>
  21. </aop:config>
  22.  
  23. </beans>
  • 测试类
  1. package cn.demo2;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext2.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("productDAO")
  15. private ProductDAO productDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. productDAO.add();
  20. productDAO.delete();
  21. productDAO.find();
  22. productDAO.update();
  23. }
  24.  
  25. }

1.5 Spring的JDBC Template

1.5.1JDBC Template

  • Spring JDBC是Spring提供的持久层技术。
  • 简化JDBC API开发,使用上和Apache公司的DButils框架类似。

1.5.2Spring对不同持久层技术的支持

  • Spring为各种支持的持久化技术,都提供了简单模板和回调
ORM持久层技术 模板类
JDBC

org.springframework.jdbc.core.JdbcTemplate

Hibernate3.0

org.springframework.orm.hibernate3.HibernateTemplate

IBatis(MyBatis)

org.springframework.orm.ibatis.SqlMapClientTemplate

JPA

org.springframework.orm.jpa.JpaTemplate

1.5.3 开发JDBC Template入门

  • 引入jar包

    • spring-beans-3.2.0.RELEASE.jar
    • spring-context-3.2.0.RELEASE.jar
    • spring-core-3.2.0.RELEASE.jar
    • spring-expression-3.2.0.RELEASE.jar
    • com.springsource.org.apache.commons.logging-1.1.1.jar
    • com.springsource.org.apache.log4j-1.2.15.jar
    • spring-jdbc-3.2.0.RELEASE.jar
    • spring-tx-3.2.0.RELEASE.jar
    • 数据库驱动
  • 创建applicationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. </beans>
  • 测试
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.jdbc.core.JdbcTemplate;
  5. import org.springframework.jdbc.datasource.DriverManagerDataSource;
  6.  
  7. public class SpringTest {
  8. @Test
  9. public void demo1(){
  10. //创建连接池
  11. DriverManagerDataSource dataSource = new DriverManagerDataSource();
  12. //设置参数
  13. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  14. dataSource.setUrl("jdbc:mysql:///spring3_day02");
  15. dataSource.setUsername("root");
  16. dataSource.setPassword("root");
  17. //使用JDBC模板
  18. JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  19. jdbcTemplate.execute("create table user( id int primary key auto_increment,name varchar(20))");
  20.  
  21. }
  22. }

1.5.4配置连接池

  • Spring默认的连接池

    • applicationContext.xml  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. <!-- 配置Spring默认的连接池 -->
  13. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  14. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  15. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  16. <property name="username" value="root"/>
  17. <property name="password" value="root"/>
  18. </bean>
  19.  
  20. <!-- 定义JDBC Template -->
  21. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  22. <property name="dataSource" ref="dataSource"/>
  23. </bean>
  24. </beans>
    • 测试类
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. import org.springframework.jdbc.core.JdbcTemplate;
  7.  
  8. public class SpringTest {
  9.  
  10. @Test
  11. public void demo2(){
  12. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  13. JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
  14. jdbcTemplate.execute("insert into user (name) values ('哈哈')");
  15.  
  16. }
  17. }
  • DBCP连接池

    • 导入jar包

      • com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
      • com.springsource.org.apache.commons.pool-1.5.3.jar
    • applicationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. <!-- 配置Spring默认的连接池 -->
  13. <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  14. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  15. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  16. <property name="username" value="root"/>
  17. <property name="password" value="root"/>
  18. </bean> -->
  19.  
  20. <!-- 配置DBCP连接池 -->
  21. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  23. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  24. <property name="username" value="root"/>
  25. <property name="password" value="root"/>
  26. </bean>
  27.  
  28. <!-- 定义JDBC Template -->
  29. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  30. <property name="dataSource" ref="dataSource"/>
  31. </bean>
  32. </beans>
    • 测试类
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. import org.springframework.jdbc.core.JdbcTemplate;
  7.  
  8. public class SpringTest {
  9.  
  10. @Test
  11. public void demo2(){
  12. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  13. JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
  14. jdbcTemplate.execute("insert into user (name) values ('呵呵')");
  15.  
  16. }
  17. }
  • C3p0连接池

    • 导入jar包

      • com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
    • applicationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. <!-- 配置Spring默认的连接池 -->
  13. <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  14. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  15. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  16. <property name="username" value="root"/>
  17. <property name="password" value="root"/>
  18. </bean> -->
  19.  
  20. <!-- 配置DBCP连接池 -->
  21. <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  23. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  24. <property name="username" value="root"/>
  25. <property name="password" value="root"/>
  26. </bean> -->
  27.  
  28. <!-- 配置C3p0连接池 -->
  29. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  30. <property name="driverClass" value="com.mysql.jdbc.Driver"/>
  31. <property name="jdbcUrl" value="jdbc:mysql:///spring3_day02"/>
  32. <property name="user" value="root"/>
  33. <property name="password" value="root"/>
  34. </bean>
  35.  
  36. <!-- 定义JDBC Template -->
  37. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  38. <property name="dataSource" ref="dataSource"/>
  39. </bean>
  40. </beans>
    • 测试类
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. import org.springframework.jdbc.core.JdbcTemplate;
  7.  
  8. public class SpringTest {
  9.  
  10. @Test
  11. public void demo2(){
  12. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  13. JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
  14. jdbcTemplate.execute("insert into user (name) values ('嘻嘻')");
  15.  
  16. }
  17. }

1.5.5设置参数到属性文件

  • 在src下新建了一个jdbc.properties
  1. driverClass=com.mysql.jdbc.Driver
  2. jdbcUrl=jdbc:mysql:///spring3_day02
  3. user=root
  4. password=root
  • 需要在applicationContext.xml使用属性文件配置的内容

    • 第一种写法
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. <!-- 配置Spring默认的连接池 -->
  13. <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  14. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  15. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  16. <property name="username" value="root"/>
  17. <property name="password" value="root"/>
  18. </bean> -->
  19.  
  20. <!-- 配置DBCP连接池 -->
  21. <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  23. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  24. <property name="username" value="root"/>
  25. <property name="password" value="root"/>
  26. </bean> -->
  27.  
  28. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  29. <property name="location" value="classpath:jdbc.properties"></property>
  30. </bean>
  31.  
  32. <!-- 配置C3p0连接池 -->
  33. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  34. <property name="driverClass" value="${driverClass}"/>
  35. <property name="jdbcUrl" value="${jdbcUrl}"/>
  36. <property name="user" value="${user}"/>
  37. <property name="password" value="${password}"/>
  38. </bean>
  39.  
  40. <!-- 定义JDBC Template -->
  41. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  42. <property name="dataSource" ref="dataSource"/>
  43. </bean>
  44. </beans>
    • 第二种写法
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. <!-- 配置Spring默认的连接池 -->
  13. <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  14. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  15. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  16. <property name="username" value="root"/>
  17. <property name="password" value="root"/>
  18. </bean> -->
  19.  
  20. <!-- 配置DBCP连接池 -->
  21. <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  23. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  24. <property name="username" value="root"/>
  25. <property name="password" value="root"/>
  26. </bean> -->
  27.  
  28. <!-- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  29. <property name="location" value="classpath:jdbc.properties"></property>
  30. </bean> -->
  31. <context:property-placeholder location="classpath:jdbc.properties"/>
  32.  
  33. <!-- 配置C3p0连接池 -->
  34. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  35. <property name="driverClass" value="${driverClass}"/>
  36. <property name="jdbcUrl" value="${jdbcUrl}"/>
  37. <property name="user" value="${user}"/>
  38. <property name="password" value="${password}"/>
  39. </bean>
  40.  
  41. <!-- 定义JDBC Template -->
  42. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  43. <property name="dataSource" ref="dataSource"/>
  44. </bean>
  45. </beans>
  • 测试
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. import org.springframework.jdbc.core.JdbcTemplate;
  7.  
  8. public class SpringTest {
  9.  
  10. @Test
  11. public void demo2(){
  12. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  13. JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
  14. jdbcTemplate.execute("insert into user (name) values ('笨笨')");
  15.  
  16. }
  17. }

1.5.6JDBC Template的CRUD操作

  • 为了方便DAO中注入JdbcTemplate,Spring为每一个持久化技术都提供了支持类。
ORM持久化技术 支持类
JDBC

org.springframework.jdbc.core.support.JdbcDaoSupport

 Hibernate3.0

org.springframework.orm.hibernate3.support.HibernateDaoSupport

 iBatis

org.springframework.orm.ibatis.support.SqlMapClientDaoSupport

  

  

    

      

1.5.7JDBC Template的增、删、改操作

  • 实体类User
  1. package cn.demo1;
  2.  
  3. public class User {
  4. private Integer id;
  5. private String name;
  6.  
  7. public Integer getId() {
  8. return id;
  9. }
  10. public void setId(Integer id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19.  
  20. }
  • UserDAO
  1. package cn.demo1;
  2.  
  3. import org.springframework.jdbc.core.support.JdbcDaoSupport;
  4.  
  5. public class UserDAO extends JdbcDaoSupport{
  6.  
  7. public void add(User user){
  8. String sql = "insert into user values(null,?)";
  9. this.getJdbcTemplate().update(sql, user.getName());
  10. }
  11.  
  12. public void update(User user){
  13. String sql = "update user set name = ? where id = ?";
  14. this.getJdbcTemplate().update(sql, user.getName(),user.getId());
  15. }
  16.  
  17. public void delete(User user){
  18. String sql = "delete from user where id = ?";
  19. this.getJdbcTemplate().update(sql, user.getId());
  20. }
  21.  
  22. }
  • jdbc.properties
  1. driverClass=com.mysql.jdbc.Driver
  2. jdbcUrl=jdbc:mysql:///spring3_day02
  3. user=root
  4. password=root
  • applicationContext.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  11.  
  12. <!-- 配置Spring默认的连接池 -->
  13. <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  14. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  15. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  16. <property name="username" value="root"/>
  17. <property name="password" value="root"/>
  18. </bean> -->
  19.  
  20. <!-- 配置DBCP连接池 -->
  21. <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  23. <property name="url" value="jdbc:mysql:///spring3_day02"/>
  24. <property name="username" value="root"/>
  25. <property name="password" value="root"/>
  26. </bean> -->
  27.  
  28. <!-- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  29. <property name="location" value="classpath:jdbc.properties"></property>
  30. </bean> -->
  31. <context:property-placeholder location="classpath:jdbc.properties"/>
  32.  
  33. <!-- 配置C3p0连接池 -->
  34. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  35. <property name="driverClass" value="${driverClass}"/>
  36. <property name="jdbcUrl" value="${jdbcUrl}"/>
  37. <property name="user" value="${user}"/>
  38. <property name="password" value="${password}"/>
  39. </bean>
  40.  
  41. <!-- 定义JDBC Template -->
  42. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  43. <property name="dataSource" ref="dataSource"/>
  44. </bean>
  45.  
  46. <bean id="userDAO" class="cn.demo1.UserDAO">
  47. <property name="jdbcTemplate" ref="jdbcTemplate"/>
  48. </bean>
  49.  
  50. </beans>
  • 测试类
  1. package cn.demo1;
  2.  
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.test.context.ContextConfiguration;
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  9.  
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration("classpath:applicationContext.xml")
  12. public class SpringTest {
  13. @Autowired
  14. @Qualifier("userDAO")
  15. private UserDAO userDAO;
  16.  
  17. @Test
  18. public void demo1(){
  19. User user = new User();
  20. user.setName("哈哈");
  21. userDAO.add(user);
  22. }
  23. @Test
  24. public void demo2(){
  25. User user = new User();
  26. user.setId(1);
  27. user.setName("呵呵");
  28. userDAO.update(user);
  29. }
  30. @Test
  31. public void demo3(){
  32. User user = new User();
  33. user.setId(1);
  34. userDAO.delete(user);
  35. }
  36.  
  37. }

1.5.8JDBC Template的查询操作

  • 简单查询

    • select count(*) from user;
    • select name from user where id = ?;
  1. public int findCount(){
  2. String sql = "select count(*) from user";
  3. return this.getJdbcTemplate().queryForInt(sql);
  4.  
  5. }
  1.   @Test
  2. public void demo4(){
  3. System.out.println("总共:"+userDAO.findCount());
  4. }
  1. public String findNameById(int id){
  2. String sql = "select name from user where id = ?";
  3. return this.getJdbcTemplate().queryForObject(sql,String.class,id);
  4. }
  1. @Test
  2. public void demo5(){
  3. System.out.println(userDAO.findNameById(1));
  4. }
  • 复杂查询:返回对象和对象集合

    • select * from user where id = ?;
    • select * from user;      
  1. public User findById(int id){
  2. String sql = "select * from user where id = ?";
  3. return (User) this.getJdbcTemplate().query(sql,new ResultSetExtractor<User>(){
  4.  
  5. @Override
  6. public User extractData(ResultSet rs) throws SQLException, DataAccessException {
  7. User user = new User();
  8. if(rs.next()){
  9. user.setId(rs.getInt(1));
  10. user.setName(rs.getString(2));
  11. }
  12.  
  13. return user;
  14. }
  15.  
  16. }, id);
  17. }
  1. @Test
  2. public void demo6(){
  3. User user = userDAO.findById(2);
  4. System.out.println(user.getId()+","+user.getName());
  5. }
  1. public List<User> findAll(){
  2. String sql = "select * from user";
  3. return this.getJdbcTemplate().query(sql, new RowMapper<User>(){
  4.  
  5. @Override
  6. public User mapRow(ResultSet rs, int paramInt) throws SQLException {
  7. User user = new User();
  8. user.setId(rs.getInt(1));
  9. user.setName(rs.getString(2));
  10. return user;
  11. }});
  12. }
  1. @Test
  2. public void demo7(){
  3. List<User> users = userDAO.findAll();
  4. for (User user : users) {
  5. System.out.println(user.getId()+","+user.getName());
  6. }
  7. }

Spring(二)的更多相关文章

  1. spring(二、bean生命周期、用到的设计模式、常用注解)

    spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...

  2. Spring(二)Bean入门

    一.BeanFactory介绍 1.1.Bean: 在Spring技术中是基于组件的 最基本了是最常用的单元 其实实例保存在Spring的容器当中 Bean通常被定义在配置文件当中,Bean实例化由S ...

  3. Spring(二)——IoC

    IoC(Inversion of Control)称之为控制反转,指的是在Spring框架的配置文件中声明对象,由框架负责创建对象,这叫做控制反转.实现方式有两种:DI(Dependency Inje ...

  4. spring(二) AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  5. Spring(二)之入门示例

    任何编程技术,特别是入门示例,通常都是Hello World,在这里我也遵循这个业界公认的原则. 这里我使用的maven项目,大家如果想要演示,建议使用Eclipse(含maven插件)或Idea(含 ...

  6. Spring(二十)之使用Log4j记录日志

    日志记录,也是常用的,比如异常信息记录或者其他相关信息记录,良好的日志记录有助于当系统出现某些不是特别大的问题时,可及时通过日志信息,捕捉到异常,从而确定是那段代码的问题,避免影响其他的代码. 关于m ...

  7. Spring(二) -- 春风拂面之 核心 AOP

    ”万物皆对象“是面向对象编程思想OOP(Object Oriented Programming) 的最高境界.在面向对象中,我一直将自己(开发者)放在一个至高无上的位置上,可以操纵万物(对象),犹如一 ...

  8. Spring(二)--IoC&AOP

    IOC 一.IOC概述: 一般指控制反转(inversion of Control),把创建对象的权利交给框架,Ioc容器控制对象,是框架的重要特征,并非是面向对象编程的专用术语.它包括依赖注入(DI ...

  9. Spring(二)scope、集合注入、自动装配、生命周期

    原文链接:http://www.orlion.ga/189/ 一.scope bean的scope属性中常用的有两种:singleton(单例,默认)和prototype(原型,每次创建新对象) 例: ...

  10. 学习Spring(二) 调用静态工厂方法创建Bean

    1,创建抽象的产品类 package com.robert.spring.shop; public abstract class Product { } 2,创建具体产品类 package com.r ...

随机推荐

  1. EF查询百万级数据的性能测试

    一.起因  个人还是比较喜欢EF的,毕竟不用写Sql,开发效率高,操作简单,不过总是听人说EF的性能不是很好,也看过别人做的测试,但是看了就以为真的是那样.但是实际上到底是怎么样,说实话我真的不知道. ...

  2. php---tp框架---表单验证

    自动验证是ThinkPHP模型层提供的一种数据验证方法,可以在使用create创建数据对象的时候自动进行数据验证.分为静态验证和动态验证. 关于基础知识,请查看手册"自动验证"一章 ...

  3. OpenCV 之 网络摄像头

     1  RTSP RTSP (Real Time Streaming Protocol),是一种语法和操作类似 HTTP 协议,专门用于音频和视频的应用层协议. 和 HTTP 类似,RTSP 也使用 ...

  4. Oracle查询多行数据合并成一行数据

    例如: select base_id, translate (ltrim (text1, '/'), '*/', '*,') xmmc,translate (ltrim (text2, '/'), ' ...

  5. 20170711_map/reduce

    js: map: var arr = [1,2,3,4,5]; var res = arr.map(function(x){ return x * x; }); //res 现在 = [1,4,9,1 ...

  6. java.util.Arrays类

    前言:java.util.Arrays类的技术文档请查看Oracle官网 1.Arrays类常见方法: 本文参考资料:百度文库:Oracle官网:第三方中文技术文档

  7. Docker初步了解

    Docker 是什么 https://www.docker.com/ Docker 这个单词英文原意是码头工人,搬运工的意思,这个搬运工搬运的是各种应用的容器. 官方的说法是,Docker 是提供给开 ...

  8. linux的文件权限与目录配置<----->第二章

    1.Linux文件属性    [   1  ]                  [   2  ] [    3    ]  [    4    ]  [ 5 ]             [ 6 ] ...

  9. Nlpir Parser敏感词搜索灵玖语义技术应用

    近年来随着网络技术的飞速发展和用户的剧烈增长,网络传输数据量越来越大,网络用语越来越趋于多样化.如何快速的屏蔽用户的不当言论.过滤用户发表内容中的非法词汇已成为关键词匹配领域的一项重大难题. 目前主要 ...

  10. year:2017 month:07 day:31

    2017-07-31 JAVA se 1:基础 控制语句:continue语句:退出本次循环 break语句:退出当前循环 循环语句:for(初始化:条件表达式:循环体){循环语句} 先初始化,再执行 ...