Spring study notes (b)

Spring study notes (b)

This is a precipitation process, probably first contact Spring at this time last year, had in training, initial contact with Java web, direct learning SSM frame (when the Servlet is no school), then, to develop a very bad study habits, is "Zhaomaohuahu." What do others, according to the way it wants, without any thought, this study habits certainly will not go too far. Now I have a lot of doubt, what is this? Why do this? How to do better? So the theme of this note is " What's this? "

1. AOP

1.1 AOP Introduction

1.1.1 What is AOP

  • In the software industry, AOP is the abbreviation for Aspect Oriented Programming, meaning: Aspect Oriented Programming, by way of pre-compiler and run-time dynamic proxy implementation of uniform maintenance program features a technology. AOP is of OOP (object oriented programming) continuation is a hot software development, is an important element in the Spring Framework is a functional programming Yan Shengfan type. AOP can use to isolate each part of the business logic such that the business logic to reduce the degree of coupling between the parts, improve the reusability of the program, while improving efficiency of development.
  • AOP taken transverse extraction mechanism replacing the traditional longitudinal succession repetitive coding system
  • Classic applications: transaction management, performance monitoring, security checks, cache, logs, etc.
  • Spring AOP using pure Java implementation does not require special compilation process and the class loader at runtime woven into the code to enhance the target class by way of proxy
  • AspectJ AOP framework is a Java-based start Spring2.0, Spring AOP support for the introduction of Aspect, AspectJ extends the Java language, provides a dedicated compiler, at compile time code provided in the lateral weaving

1.1.2 AOP implementation principle

  • aop agent will use the underlying mechanisms implemented.
  • The interface and implementation class: spring of the dynamic agent Proxy jdk.
  • Implementation class: spring cglib using bytecode enhancement.

1.1.2 AOP term

  1. target target class: to be the agent class. For example: UserService
  2. Joinpoint connection point: the so-called connection points are those methods may be intercepted. For example: all methods
  3. PointCut entry point: the connection point has been enhanced. For example: addUser ()

  4. advice notice / enhancement, enhancement code. For example: after, before
  5. Weaving weaving: refers to the application of reinforced advice to target audiences to the process of creating a new proxy object proxy.
  6. proxy proxy class
  7. Aspect section: the entry point of the binding pointcut advice notification and
    a line is a special surface.
    And an entry point for a notification, as a particular surface composition.
    the term

1.2 manual

1.2.1 JDK dynamic proxies

  • JDK dynamic proxies simplify the "decorator" Design Patterns. Use the premise: there must be an interface
  1. Target class: the interface and implementation class
  2. Aspect class: for storing notification MyAspect
  3. Factory class: the preparation plant to generate proxy
  4. test
    jdk dynamic proxy

    1.2.1.1 target class
public interface UserService {

    void addUser();
    void updateUser();
    void deleteUser();
}
Class section 1.2.1.2
public class MyAspect {

    public void before(){
        System.out.println("this is before");
    }

    public void after(){
        System.out.println("this is after");
    }
}
1.2.1.3 Factory
public class MyBeanFactory {

    public static UserService createService(){
        //1 目标类
        final UserService userService = new UserServiceImpl();
        //2 切面类
        final MyAspect myAspect = new MyAspect();
        /**
         * 3 代理类:将目标类(切入点)和 切面类(通知) 结合 --> 切面
         *  Proxy.newProxyInstance
         *      参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。
         *          一般情况:当前类.class.getClassLoader();
         *          目标类实例.getClass().get...
         *      参数2:Class[] interfaces 代理类需要实现的所有接口
         *          方式1:目标类实例.getClass().getInterfaces()  ;注意:只能获得自己接口,不能获得父元素接口
         *          方式2:new Class[]{UserService.class}
         *          例如:jdbc 驱动  --> DriverManager  获得接口 Connection
         *      参数3:InvocationHandler  处理类,接口,必须进行实现类,一般采用匿名内部
         *          提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke
         *              参数31:Object proxy :代理对象
         *              参数32:Method method : 代理对象当前执行的方法的描述对象(反射)
         *                  执行方法名:method.getName()
         *                  执行方法:method.invoke(对象,实际参数)
         *              参数33:Object[] args :方法实际参数
         *
         */
        UserService proxService = (UserService) Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
                userService.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        //前执行
                        myAspect.before();

                        //执行目标类的方法
                        Object obj = method.invoke(userService,args);

                        //后方法
                        myAspect.after();

                        return obj;
                    }
                }
        );
        return proxService;
    }
    }
}
1.2.1.4 Test class
    @Test
    public void demo01(){
        UserService userService = MyBeanFactory.createService();
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

1.2.2 CGLIB bytecode enhancement

  • No interface, only the implementation class
  • CGLIB bytecode using a reinforced frame, creating a subclass of the target class at run-time, thereby enhancing the target classes.
  • Import jar package:
    their leader packet (Learn):
    Core: hibernate-distribution-3.6.10.Final \ lib \ bytecode \ cglib \ cglib-2.2.jar
    dependent: struts-2.3.15.3 \ apps \ struts2 -blank \ WEB- INF \ lib \ asm-3.3.jar
    the Spring-core..jar has integrated more than two content
    CCGLIB agent
1.2.2.1 Factory class
public class MyBeanFactory {

    public static UserService createService(){
        //1 目标类
        final UserService userService = new UserServiceImpl();
        //2 切面类
        final MyAspect myAspect = new MyAspect();
        // 3.代理类 ,采用cglib ,底层创建目标类的子类
        // 3.1 核心类
        Enhancer enhancer = new Enhancer();
        // 3.2 确定父类
        enhancer.setSuperclass(userService.getClass());

        /**
         * 3.3 设置回调函数 , MethodInterceptor接口 等效 jdk InvocationHander接口
         *      intercept() 等效 jdk  invoke()
         *          参数1、参数2、参数3:以invoke一样
         *          参数4:methodProxy 方法的代理
         */

        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                //前执行
                myAspect.before();

                //执行目标类方法
                Object obj = method.invoke(userService,objects);
                // * 执行代理类的父类,执行目标类(目标类和代理类 父子关系)
             //   methodProxy.invokeSuper(o,objects);

                //后执行
                myAspect.after();
                return obj;
            }
        });
        //3.4 创建代理
        UserServiceImpl proxService = (UserServiceImpl) enhancer.create();

        return proxService;
    }
}

1.3 AOP Alliance notification type

  • AOP Alliance notification Advice defines org.aopalliance.aop.Advice
  • Advice in accordance with the notice Spring connection point position of the target class methods can be divided into five categories
    • Before advice org.springframework.aop.MethodBeforeAdvice
      • Before the implementation of enhanced target execution method
    • After returning advice org.springframework.aop.AfterReturningAdvice
      • After certain embodiments enhancement method is performed
    • Around advice org.aopalliance.intercept.MethodInterceptor
      • Before and after the target method to enhance the implementation of the Executive
    • An exception is thrown notice org.springframework.aop.ThrowsAdvice
      • After the implementation of enhanced method throws an exception
    • Introducing notification org.springframework.aop.IntroductionInterceptor
      • Add some new methods and properties in the target class
      环绕通知,必须手动执行目标方法
      try{
       //前置通知
       //执行目标方法
       //后置通知
      } catch(){
       //抛出异常通知
      }

      1.4 spring to prepare Agent: semi-automatic

  • Let spring to create a proxy object, the proxy object acquired from spring container manually.
  • Import jar package:
    Core: +. 1. 4
    the AOP: the AOP Alliance (specification), spring-aop (implemented)
    jar

1.4.1 target class

public interface UserService {

    void addUser();
    void updateUser();
    void deleteUser();
}

Class section 1.4.2

/**
 *  切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。
 *  采用“环绕通知” MethodInterceptor
 */
public class MyAspect implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("this is before");

        //手动执行目标方法
        Object obj = methodInvocation.proceed();

        System.out.println("this is after");
        return obj;
    }
}

1.4.3 spring configuration

    <!-- 1 创建目标类-->
    <bean id="userService" class="com.springlearning.spring_proxy.UserServiceImpl"></bean>
    <!-- 2 创建切面类-->
    <bean id="myAspect" class="com.springlearning.spring_proxy.MyAspect"></bean>

    <!-- 3 创建代理类
         * 使用工厂bean FactoryBean ,底层调用getObject() 返回特殊bean
         * ProxyFactoryBean 用于创建代理工厂bean ,生成特殊代理对象
                interfaces : 确定接口们
                    通过<array> 可以设置多个值
                    只有一个值时, value=""
                target : 确定目标类
                interceptorNames : 通知 切面类的名称,类型String[], 如果设置一个值 value=""
                optimize :强制使用cglib
                    <property name="optimize" value="true"></property>
          底层机制
                如果目标类有接口,采用jdk动态代理
                如果没有接口,采用cglib 字节码增强
                如果声明 optimize = true ,无论是否有接口 ,都采用cglib
    -->
    <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="interfaces" value="com.springlearning.spring_proxy.UserService"></property>
        <property name="target" ref="userService"></property>
        <property name="interceptorNames" value="myAspect"></property>
    </bean>

1.4.4 Testing

    @Test
    public void demo01(){
        String xmlPath = "com/springlearning/spring_proxy/beans.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        //获得代理类
        UserService userService = (UserService) applicationContext.getBean("proxyService");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

1.5 spring aop Programming: Automatic

  • Spring containers obtained from the target class, if AOP configuration, the spring automatically generate proxy.
  • To determine the target class, AspectJ pointcut expression, introducing jar package
  • Contains aopalliance and aspectj in spring-aop-5.0.4 version
    jar 包

  • I am here when debugging a problem, which is included in the spring-aop-5.0.4 versions of aopalliance, and I think teaching is version 3.x, the need to import additional aopalliance package, as well as a mistake aspectjrt aspectjweaver, however, two packages have different functions.

1.5.1 spring configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 1 创建目标类 -->
    <bean id="userService" class="com.springlearning.spring_proxy.UserServiceImpl"></bean>
    <!-- 2 创建切面类(通知)-->
    <bean id="myAspect" class="com.springlearning.spring_proxy.MyAspect"></bean>
    <!-- 3 aop编程
        3.1 导入命名空间
        3.2 使用 <aop:config> 进行配置
                proxy-target-class="true" 声明时使用cglib代理
            <aop:pointcut> 切入点 , 从目标对象获得具体方法
            <aop:advisor> 特殊的切面, 只用一个通知 和一个切入点
                advice-ref 通知引用
                pointcut-ref 切入点引用
        3.3 切入点表达式
            execution(* com.springlearning.spring_proxy.*.(..))
            选择方法   返回值任意  包         类名称任意  方法名任意   参数任意
    -->
    <aop:config proxy-target-class="true">
        <aop:pointcut id="myPointCut" expression="execution(* com.springlearning.spring_proxy.*.*(..))"/>
        <aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"></aop:advisor>
    </aop:config>
</beans>

1.5.2 Testing

    @Test
    public void demo01(){
        String xmlPath = "com/springlearning/spring_proxy/beans.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

        //获得代理类
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

2. AspectJ

2.1 Introduction

  • AspectJ AOP framework is based on Java language
  • Spring2.0 later added support for AspectJ expression pointcuts
  • @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
    新版本Spring框架,建议使用AspectJ方式来开发AOP
  • 主要用途:自定义开发

2.2 切入点表达式

  1. execution() 用于描述方法
    语法:execution(修饰符 返回值 包.类.方法名(参数) throws异常)
    修饰符,一般省略
    public 公共方法
    * 任意
    返回值,不能省略
    void 返回没有值
    String 返回值字符串
    * 任意
    包,[省略]
    com.springlearning.proxy 固定包
    com.springlearning.proxy..service proxy包下面子包任意 (例如:com.springlearning.proxy.staff.service)
    com.springlearning.proxy.. proxy包下面的所有子包(含自己)
    com.springlearning.proxy.
    .service.. proxy包下面任意子包,固定目录service,service目录任意包
    类,[省略]
    UserServiceImpl 指定类
    Impl 以Impl结尾
    User
    以User开头
    * 任意
    方法名,不能省略
    addUser 固定方法
    add* 以add开头
    Do 以Do结尾
    任意
    (参数)
    () 无参
    (int) 一个整型
    (int ,int) 两个
    (..) 参数任意
    throws ,可省略,一般不写。

综合 1
execution(* com.springlearning.proxy..service...*(..))

综合 2
<aop:pointcut expression="execution(* com.springlearning.WithCommit.(..)) ||
execution(* com.springlearning.Service.(..))" id="myPointCut"/>

  1. within:匹配包或子包中的方法
    within(com.springlearning.aop..*)
  2. this:匹配实现接口的代理对象中的方法
    this(com.springlearning.aop.user.UserDAO)
  3. target:匹配实现接口的目标对象中的方法
    target(com.springlearning.aop.user.UserDAO)
  4. args:匹配参数格式符合标准的方法
    args(int,int)
  5. bean(id) 对指定的bean所有的方法(了解)
    bean('userService')

2.3 AspectJ 通知类型

  • aop联盟定义通知类型,具有特性接口,必须实现,从而确定方法名称。
  • aspectj 通知类型,只定义类型名称。已经方法格式。
  • 个数:6种,知道5种,掌握1中
    before:前置通知(应用:各种校验)
    在方法执行前执行,如果通知抛出异常,阻止方法运行
    afterReturning:后置通知(应用:常规数据处理)
    方法正常返回后执行,如果方法中抛出异常,通知无法执行
    必须在方法执行后才执行,所以可以获得方法的返回值。
    around:环绕通知(应用:十分强大,可以做任何事情)
    方法执行前后分别执行,可以阻止方法的执行
    必须手动执行目标方法
    afterThrowing:抛出异常通知(应用:包装异常信息)
    方法抛出异常后执行,如果方法没有抛出异常,无法执行
    after:最终通知(应用:清理现场)
    方法执行完毕后执行,无论方法中是否出现异常
环绕

try{
     //前置:before
    //手动执行目标方法
    //后置:afterRetruning
} catch(){
    //抛出异常 afterThrowing
} finally{
    //最终 after
}

aspectj notification type
Related classes
AfterThrowing
After

2.4 导入jar包

  • 4个:
    aop联盟规范
    spring aop 实现
    aspect 规范
    spring aspect 实现

2.5 基于xml

  1. 目标类:接口 + 实现
  2. 切面类:编写多个通知,采用aspectj 通知名称任意(方法名任意)
  3. aop编程,将通知应用到目标类
  4. 测试

2.5.1 切面类

/**
 * 切面类,含有多个通知
 */
public class MyAspect {

    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知:" + joinPoint.getSignature().getName());
    }
    public void myAfterReturning(JoinPoint joinPoint,Object ret){
        System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
    }
    public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("前");
        //手动执行目标方法
        Object obj = joinPoint.proceed();
        System.out.println("后");
        return obj;
    }
    public void myAfterThrowing(JoinPoint joinPoint,Throwable throwable){
        System.out.println("抛出异常通知:" + throwable.getMessage());
    }
    public void myAfter(JoinPoint joinPoint){
        System.out.println("最终通知");
    }
}

2.5.2 spring配置

<!-- 1 创建目标类 -->
    <bean id="userService" class="com.springlearning.aspectj.UserServiceImpl"></bean>
    <!-- 2 创建切面类(通知)-->
    <bean id="myAspect" class="com.springlearning.aspectj.MyAspect"></bean>
    <!-- 3 aop编程
          <aop:aspect> 将切面类 声明“切面”,从而获得通知(方法)
                ref 切面类引用
          <aop:pointcut> 声明一个切入点,所有通知都可以使用。
                expression 切入点表达式
                id 名称,用于其他通知引用
    -->
    <aop:config>
        <aop:aspect ref="myAspect">
            <aop:pointcut id="myPointcut" expression="execution(* com.springlearning.aspectj.UserServiceImpl.*(..))"/>
            <!-- 3.1 前置通知
                <aop:before method="" pointcut="" pointcut-ref=""/>
                    method : 通知,及方法名
                    pointcut :切入点表达式,此表达式只能当前通知使用。
                    pointcut-ref : 切入点引用,可以与其他通知共享切入点。
                通知方法格式:public void myBefore(JoinPoint joinPoint){
                    参数1:org.aspectj.lang.JoinPoint  用于描述连接点(目标方法),获得目标方法名等
                例如:
            <aop:before method="myBefore" pointcut-ref="myPointCut"/>
            -->

            <!-- 3.2后置通知  ,目标方法后执行,获得返回值
                <aop:after-returning method="" pointcut-ref="" returning=""/>
                    returning 通知方法第二个参数的名称
                通知方法格式:public void myAfterReturning(JoinPoint joinPoint,Object ret){
                    参数1:连接点描述
                    参数2:类型Object,参数名 returning="ret" 配置的
                例如:
            <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />
            -->

            <!-- 3.3 环绕通知
                <aop:around method="" pointcut-ref=""/>
                通知方法格式:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
                    返回值类型:Object
                    方法名:任意
                    参数:org.aspectj.lang.ProceedingJoinPoint
                    抛出异常
                执行目标方法:Object obj = joinPoint.proceed();
                例如:
            <aop:around method="myAround" pointcut-ref="myPointCut"/>
            -->
            <!-- 3.4 抛出异常
                <aop:after-throwing method="" pointcut-ref="" throwing=""/>
                    throwing :通知方法的第二个参数名称
                通知方法格式:public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
                    参数1:连接点描述对象
                    参数2:获得异常信息,类型Throwable ,参数名由throwing="e" 配置
                例如:
            <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>
            -->
            <!-- 3.5 最终通知-->
            <aop:after method="myAfter" pointcut-ref="myPointcut"></aop:after>

        </aop:aspect>

    </aop:config>

2.6 基于注解

2.6.1 替换bean

 <!-- 1 创建目标类 -->
    <bean id="userService" class="com.springlearning.aspectj.UserServiceImpl"></bean>
    <!-- 2 创建切面类(通知)-->
    <bean id="myAspect" class="com.springlearning.aspectj.MyAspect"></bean>
@Component
public class MyAspect {
@Service("userService")
public class UserServiceImpl implements UserService {
  • 注意:扫描
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 1. 扫描 注解类 -->
    <context:component-scan base-package="com.springlearning.aspectj"></context:component-scan>

2.6.2 替换 aop

  • 必须进行aspectj 自动代理
<!-- 2.确定 aop注解生效 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 声明切面
<aop:aspect ref="myAspect"> <!--被下面注解替换 -->
@Component
@Aspect //添加注解
public class MyAspect {
  • 替换前置通知
<aop:before method="myBefore" pointcut="execution(* com.ithspringlearning.aspectj.UserServiceImpl.*(..))"/> <!--被下面注解替换 -->
    //切入点当前有效
    @Before("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知:" + joinPoint.getSignature().getName());
    }
  • 替换 公共切入点
 <aop:pointcut id="myPointcut" expression="execution(* com.springlearning.aspectj.UserServiceImpl.*(..))"/>
 <!--被下面注解替换 -->
    //声明公共切入点
    @Pointcut("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
    private void myPointCut(){}
  • 替换后置
  <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" />
    @AfterReturning(value = "myPointCut()",returning = "ret")
    public void myAfterReturning(JoinPoint joinPoint,Object ret){
        System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
    }

Quote

  • 环绕替换
  <aop:around method="myAround" pointcut-ref="myPointCut"/>
    @Around(value = "myPointCut()")
    public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("前");
        //手动执行目标方法
        Object obj = joinPoint.proceed();
        System.out.println("后");
        return obj;
    }
  • 替换抛出异常
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="throwable"/>
    @AfterThrowing(value = "myPointCut()" ,throwing = "throwable")
    public void myAfterThrowing(JoinPoint joinPoint,Throwable throwable){
        System.out.println("抛出异常通知:" + throwable.getMessage());
    }

2.6.3 切面类

/**
 * 切面类,含有多个通知
 */
@Component
@Aspect
public class MyAspect {

    //声明公共切入点
    @Pointcut("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
    private void myPointCut(){}
//    @AfterReturning(value = "myPointCut()",returning = "ret")
    public void myAfterReturning(JoinPoint joinPoint,Object ret){
        System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret);
    }
    //切入点当前有效
 //   @Before("execution(* com.springlearning.aspectj.UserServiceImpl.*(..))")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知:" + joinPoint.getSignature().getName());
    }

 //   @Around(value = "myPointCut()")
    public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("前");
        //手动执行目标方法
        Object obj = joinPoint.proceed();
        System.out.println("后");
        return obj;
    }
 //   @AfterThrowing(value = "myPointCut()" ,throwing = "throwable")
    public void myAfterThrowing(JoinPoint joinPoint,Throwable throwable){
        System.out.println("抛出异常通知:" + throwable.getMessage());
    }
    @After(value = "myPointCut()")
    public void myAfter(JoinPoint joinPoint){
        System.out.println("最终通知");
    }
}

2.6.4 spring 配置

    <!-- 1. 扫描 注解类 -->
    <context:component-scan base-package="com.springlearning.aspectj"></context:component-scan>
    
    <!-- 2.确定 aop注解生效 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.6.5 aop 注解总结

  • @Aspect statement section, modified cut classes to be notified.
  • Notice
    • Front @Before
    • @AfterReturning 后 置
    • @Around surround
    • @AfterThrowing thrown
    • @After final
  • Entry point
    • @PointCut, modification methods private void xxx () {} after the starting point obtained by reference to "method name"

3. JdbcTemplate

  • JDBC spring provided for operating the tools, similar: DBUtils.
  • The DataSource dependent connection pool (data source)

3.1 environment to build

3.1.1 Create a table

create table t_user(
  id int primary key ,
  username varchar(50),
  password varchar(32)
);

3.1.2 Import jar package

jar 包

3.1.3 javaBean

public class User {

    private Integer id;
    private String username;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

3.2 api

    @Test
    public void demo(){
        //1 创建数据源(连接池) dbcp
        BasicDataSource dataSource = new BasicDataSource();
        // * 基本4项
        dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        dataSource.setUrl("jdbc:oracle:thin:@localhost:1530/orcl");
        dataSource.setUsername("sys as sysdba");
        dataSource.setPassword("sys");
        //2  创建模板
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        //3 通过api操作
        jdbcTemplate.update("insert into t_user(id,username,password) values(?,?,?)","6", "tom","998");
    }

3.3 DBCP

    <!-- 创建数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
        <property name="url" value="jdbc:oracle:thin:@localhost:1530/orcl"></property>
        <property name="username" value="sys as sysdba"></property>
        <property name="password" value="sys"></property>
    </bean>
    <!-- 创建模板 ,需要注入数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置dao -->
    <bean id="userDao" class="com.springlearning.jdbctemplate.UserDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

3.4 Configuration C3P0

    <!-- 创建C3P0数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
        <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1530/orcl"></property>
        <property name="user" value="sys as sysdba"></property>
        <property name="password" value="sys"></property>
    </bean>
  • Note here in the jar package version c3p0 requires mchange-commons-java-0.2.3. Package, which is an auxiliary package c3p0 database connection pool, this is not available when the system starts will be reported classnotfoundexception, which is c3p0-0.9.2 after the separation of the package version, 0.9.1, or when to get a package of

3.5 Use JdbcDaoSupport

3.5.1 dao layer

package com.springlearning.jdbctemplate;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import java.util.List;

/**
 * @ClassName:UserDao
 * @author: donkey-boy
 * @date:2019/7/19 10:52
 */
public class UserDao extends JdbcDaoSupport {

    /**
      * @Author: donkey-boy
     * @Description: 更新操作
     * @Param: user
     * @Return:  void
     * @Date: 2019/7/19 15:04
     */
    public void update(User user){
        String sql = "UPDATE t_user SET username=?,password=? WHERE id=?";
        Object[] args = {user.getUsername(),user.getPassword(),user.getId()};
        this.getJdbcTemplate().update(sql,args);
    }
    /**
      * @Author: donkey-boy
     * @Description: 查询全部
     * @Param: []
     * @Return: java.util.List<com.springlearning.jdbctemplate.User>
     * @Date: 2019/7/19 15:06
     */
    public List<User> findAll(){
        List<User> userList = this.getJdbcTemplate().query("select * from t_user", BeanPropertyRowMapper.newInstance(User.class));
        return userList;
    }

    /**
      * @Author: donkey-boy
     * @Description: 获取单个用户
     * @Param: [id]
     * @Return: com.springlearning.jdbctemplate.User
     * @Date: 2019/7/19 15:06
     */
    public User getUser(int id){
        User user = this.getJdbcTemplate().queryForObject("select * from t_user where id=?", BeanPropertyRowMapper.newInstance(User.class), id);
        return user;
    }
}

3.5.2 spring Profiles

    <!--  配置dao
        * dao 继承 JdbcDaoSupport,之后只需要注入数据源,底层将自动创建模板
    -->
    <!-- 配置dao -->
    <bean id="userDao" class="com.springlearning.jdbctemplate.UserDao">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

3.5.3 source code analysis

Source

3.6 Configuration properties

3.6.1 properties file

jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.jdbcUrl=jdbc:oracle:thin:@localhost:1530/orcl
jdbc.user=sys as sysdba
jdbc.password=sys

3.6.2 spring configuration

    <!-- 加载配置文件 
        "classpath:"前缀表示 src下
        在配置文件之后通过  ${key} 获得内容
    -->
    <context:property-placeholder location="classpath:com/springlearning/jdbctemplate/jdbcInfo.properties"></context:property-placeholder>
    <!-- 创建C3P0数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

Chuan Chi podcast notes from Teaching Spring

Guess you like

Origin www.cnblogs.com/donkey-boy/p/11223983.html