Spring入门

Spring

下载

  1. 下载Spring包:spring下载
  2. 导包:
    1. spring-beans-4.1.0.RELEASE.jar
    2. spring-context-4.1.0.RELEASE.jar
    3. spring-core-4.1.0.RELEASE.jar
    4. spring-expression-4.1.0.RELEASE.jar
  3. 下载相关依赖包
    • commons-logging-1.1.1.jar

IOC

  1. IOC对象相关参数
    1. scope="prototype" 多例 得到ICO容器后什么时候用什么时候创建
    2. scope="singleton" 单例 在得到IOC容器之前就已经创建好了
    3. init-method="init" 对象在创建的时候执行的初始化方法
    4. destroy-method="destroy" 对象在销毁的时候执行的销毁方法
    5. lazy-init="true" 延迟加载 true=延迟| false=不延迟 default=false
  2. IOC对象创建
    1. 无参构造方法
       <bean id="user1" class="pojo.User"></bean>
      
    2. 有参构造方法
      1. 普通赋值
        <bean id="user2" class="pojo.User">    <property name="id" value="2"></property>    <property name="username" value="李四"></property></bean>
        
      2. set赋值
           <bean id="user3" class="pojo.User">                       <constructor-arg value="1">                                     </constructor-arg>  
            <constructor-arg value="张三">                            </constructor-arg></bean>
        
    3. 工厂方法
      1. 静态工厂方法
        <bean id="user5" class="factory.Dfactory" factory-method="b"></bean>
        
      2. 普通工厂方法
        <bean id="c" class="factory.Dfactory"></bean><bean id="user4" factory-bean="c" factory-method="a"></bean>
        

Construct Injection 依赖注入

  1. set注入
    1. 普通方法
      <!--外部注入-->
      <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl">
       </bean>
       <bean id="userService" class="com.Spring.service.impl.UserServiceImpl">   
       <property name="userDao" ref="userDao"></property></bean>
      <bean id="userAction" class="com.Spring.controller.UserAction">   
       <property name="userService" ref="userService"></property></bean>
      
    2. 内部嵌套
          <!--内部注入-->
          <bean id="userAction" class="com.Spring.controller.UserAction">                         <property name="userService">     
                    <bean class="com.Spring.service.impl.UserServiceImpl">        
                      <property name="userDao">      
                          <bean class="com.Spring.dao.impl.UserDaoImpl">                                      </bean>            
                      </property>       
                 </bean>    
              </property>
         </bean>
      
    3. p命名空间
      • 引入xmlns:p="http://www.springframework.org/schema/p"
       <!--p命名空间注入-->
       <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl">                    </bean>
       <bean id="userService" class="com.Spring.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
       <bean id="userAction" class="com.Spring.controller.UserAction" p:userService-ref="userService"></bean>
      
    4. 自动装配:
      1. byName
          <!--自动装配 byName --> 
          <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl"></bean>    
          <bean id="userService" class="com.Spring.service.impl.UserServiceImpl" autowire="byName"></bean>    
          <bean id="userAction" class="com.Spring.controller.UserAction" autowire="byName"></bean>
        
      2. byType
            <!--自动装配 byType -->
            <bean id="userDao" class="com.Spring.dao.impl.UserDaoImpl">     </bean>
            <bean id="userService" class="com.Spring.service.impl.UserServiceImpl" autowire="byType">
            </bean>
            <bean id="userAction" class="com.Spring.controller.UserAction" autowire="byType"></bean>
        
  2. 注解
    1. 需要环境: 帮助文档搜索xmlns:context
        xmlns:context="http://www.springframework.org/schema/context"
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd   
      
      1. @Repository : dao层
      2. @Service : service层
      3. @Controller : controller层
      4. @Component : 普通注解
      5. @Resource : 对象注解

AOP

  1. 代理 参考博客:三种代理模式
    • 接口
    ```java
        package com.Spring.test;
        /** 
        * @Author Jamin <br> 
        *  @Date 2019/3/26 15:43 <br> 
        * @Description 接口 
        */public interface SALE {  String sale(int money);}
     ```
    
    • 实现类

          package com.Spring.test;
          /** 
          * @Author Jamin <br> 
          * @Date 2019/3/26 15:44 <br> 
          * @Description * 目标对象 
          * */
          public class Apple{  public String sale(int money)          {      
          return "卖苹果手机";  }}
      
      1. 静态代理: 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.
       package com.Spring.test;
      
          /**
          * @Author Jamin <br>
          * @Date 2019/3/26 15:47 <br>
          * @Description
          *
          *
          * 静态代理
          */
          public class AppleProxy implements SALE {
              private Apple apple = new Apple();
              public AppleProxy(Apple apple) {
                  this.apple = apple;
              }
      
              @Override
              public String sale(int money) {
      
                  String s=apple.sale(money);
                  String a="买手机送手机壳";
                  return s+a;
              }
          }
      
      
      1. 动态代理 需要给出代理对象的类型 需要给出代理对象接口的类型
             package com.Spring.test;
      
         import java.lang.reflect.InvocationHandler;
         import java.lang.reflect.Method;
         import java.lang.reflect.Proxy;
      
         /**
         * @Author Jamin <br>
         * @Date 2019/3/26 16:19 <br>
         * @Description
         */
         public class SaleFactory {
         private Object o;
      
         public SaleFactory(Object o) {
             this.o = o;
         }
      
         public Object factory() {
             return Proxy.newProxyInstance(
                 o.getClass().getClassLoader(),
                 o.getClass().getInterfaces(),
                 new InvocationHandler() {
                 /**
                 *
                 * @param proxy 被代理的对象
                 * @param method  要调用的方法
                 * @param args   方法调用时所需要的参数
                 */
                 @Override
                 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                     System.out.println("aaaaaaaaaaaaaaa");
                     Object invoke = method.invoke(o, args);
                     System.out.println("bbbbbbbbbbbbbbb");
                     return invoke;
                 }
                 });
         }
         }
      
      
      1. Cglib代理 子类代理
            package com.Spring.test;
        
        import org.springframework.cglib.proxy.Enhancer;
        import org.springframework.cglib.proxy.MethodInterceptor;
        import org.springframework.cglib.proxy.MethodProxy;
        
        import java.lang.reflect.Method;
        
        /**
        * @Author Jamin <br>
        * @Date 2019/3/26 17:15 <br>
        * @Description
        */
        public class Cglib implements MethodInterceptor {
        private Object o;
        
        public Cglib(Object o) {
            this.o = o;
        }
        
        public Object getProxy() {
            Enhancer en = new Enhancer();
            en.setSuperclass(o.getClass());
            en.setCallback(this);
            return en.create();
        }
        
        @Override
        public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy)
            throws Throwable {
            System.out.println("aaaaaaaaaaaaa");
            Object invoke = method.invoke(o, objects);
            System.out.println("bbbbbbbbbbbb");
            return invoke;
        }
        }
        
        
  2. AOP
    1. 概念:

      1. 是一种编程范式,不是一种编程语言
      2. 解决特定问题,不是解决所有问题
      3. 是OOP的补充,不是替代
    2. 好处:

      1. 集中处理某一关注点/横切逻辑
      2. 方便添加/删除关注点
      3. 侵入性少,增强代码可读性及可维护性
    3. 应用场景

      1. 权限控制
      2. 缓存控制
      3. 事务控制
      4. 审计日志
      5. 性能监控
      6. 分布式追踪
      7. 异常处理
    4. 名词解释

      1. 连接点
        • 目标对象中所有可以增强的方法
      2. 切入点
        • 目标对象中已经增强的方法
      3. 目标对象Target
        • 代理的目标对象(被代理的对象)
      4. 通知
        1. 目标方法在切面运行时的方法
        2. 通知类型
          1. 前置通知(before)
          2. 后置通知(after)
          3. 异常通知(after-throwing)
          4. 返回通知(after-returning)(异常不会执行)
          5. 环绕通知(around)
      5. 织入Weaving
        • 将通知应用到切入点的过程
      6. 代理Proxy
        • 将通知织入到目标对象之后形成的代理
    5. 使用

      1. 导包
        • com.springsource.org.aopalliance-1.0.0.jar
        • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
        • spring-aspects-4.1.0.RELEASE.jar
      2. 创建目标对象
      3. 创建通知对象
      4. 将对象织入到目标对象中
      5. 配置切入点
      6. 指定通知
    6. 代码

      1. 第一种方式
        1. 配置文件
          <!--创建目标对象-->
          <bean id="empServiceImpl" class="com.spring.EmpService.EmpServiceImpl"></bean>
          <!--创建代理对象-->
          <bean id="empAop" class="com.spring.aop.EmpAop"></bean>               
          <!--将对象织入目标对象中-->
          <aop:config>
          <!--配置切入点-->
              <aop:pointcut id="pt" expression="execution(* com.spring.EmpService.EmpServiceImpl.*())"></aop:pointcut>
          <!--指定通知-->
              <aop:aspect ref="empAop">
              <aop:before method="getBefore" pointcut-ref="pt"></aop:before>
              <aop:after method="getAfter" pointcut-ref="pt"></aop:after>
              <aop:around method="getRound" pointcut-ref="pt"></aop:around>
              <aop:after-returning method="getReturn" pointcut-ref="pt"></aop:after-returning>
              <aop:after-throwing method="getThrowable" pointcut-ref="pt"></aop:after-throwing>
              </aop:aspect>
          </aop:config>
          
        2. 方法
               package com.spring.aop;
          
              import org.aspectj.lang.ProceedingJoinPoint;
          
              /**
              * @Author Jamin <br>
              * @Date 2019/3/27 10:22 <br>
              * @Description
              */
              public class EmpAop {
          
              /** 前置通知 */
              public void getBefore() {
                  System.out.println("前置通知");
              }
              /*后置通知*/
              public void getAfter() {
                  System.out.println("后置通知");
              }
              /*环绕通知*/
              public Object getRound(ProceedingJoinPoint pj) throws Throwable {
                  System.out.println("环绕通知前");
                  Object proceed = pj.proceed();
                  System.out.println("环绕通知后");
                  return proceed;
              }
              /*返回通知*/
              public void getReturn() {
                  System.out.println("返回通知");
              }
              /*异常通知*/
              public void getThrowable() {
                  System.out.println("异常通知");
              }
              }
          
      2. 第二种方式 注解配置
        1. 配置文件
            <!--创建目标对象-->
            <bean id="empServiceImpl" class="com.spring.EmpService.EmpServiceImpl"></bean>
            <!--创建代理对象-->
            <bean id="empAop2" class="com.spring.aop.EmpAop2"></bean>
            <!--开启自动代理-->
            <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
          
        2. 方法
                        package com.spring.aop;
          
            import org.aspectj.lang.ProceedingJoinPoint;
            import org.aspectj.lang.annotation.*;
            import org.springframework.core.annotation.Order;
          
            /**
            * @Author Jamin <br>
            * @Date 2019/3/27 14:02 <br>
            * @Description
            */
            @Aspect
            public class EmpAop2 {
            @Pointcut("execution(* com.spring.EmpService.EmpServiceImpl.*())")
            public void pointCut() {}
          
            /** 前置通知 */
            @Before("pointCut()")
            public void getBefore() {
                System.out.println("前置通知");
            }
          
            /*返回通知*/
            @AfterReturning("pointCut()")
            public void getReturn() {
                System.out.println("返回通知");
            }
            /*后置通知*/
            @After("pointCut()")
            public void getAfter() {
                System.out.println("后置通知");
            }
            /*环绕通知*/
            @Order(2)
            @Around("pointCut()")
            public Object getRound(ProceedingJoinPoint pj) throws Throwable {
                System.out.println("环绕通知前");
                Object proceed = pj.proceed();
                System.out.println("环绕通知后");
                return proceed;
            }
            /*异常通知*/
            @AfterThrowing("pointCut()")
            public void getThrowable() {
                System.out.println("异常通知");
            }
            }
          

Spring中的事务

  1. 事务的概念
    • 事务是逻辑上的一组操作,要么都执行,要么都不执行
  2. 事物的特征
    • 原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
    • 一致性:执行事务前后,数据保持一致;
    • 隔离性:并发访问数据库时,一个用户的事物不被其他事物所干扰,各并发事务之间数据库是独立的;
    • 持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
  3. 并发事务带来的问题
    1. 脏读[Dirty read] : 当一个事务正在访问数据并对事务进行了修改但并未提交,另一个事务也访问这条数据并使用了这条脏数据
    2. 丢失修改:两个事务同时访问一条数据并进行修改,第一个事务的修改结果就丢失了
    3. 不可重复读:一个事务多次读同一个数据,还没有结束时,第二个事务修改了这条数据导致第一个事务读到的数据不一致
    4. 幻读: 一个事务读取了几条数据,第二个事务添加了几条数据,导致第一个事务在随后的查询中发现了一些不存在的数据
      • 与不可重复读的区别:不可重复读的重点在修改,幻读的重点在于新增和删除
  4. 解决读的问题
    • 设置隔离级别
  5. Spring事务处理:声明式事务处理
    1. xml形式
      <!-- 定义事务管理器 -->
      <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSources"/>
      </bean>
      <!--配置事务通知-->
      <tx:advice id="txadvice" transaction-manager="transactionManager">
          <!--事务操作-->
          <tx:attributes>
              <tx:method name="account*"/>
          </tx:attributes>
      </tx:advice>
      <!--切面配置-->
      <aop:config>
          <!--切入点service层的实现方法-->
          <aop:pointcut id="pt" expression="execution(* com.springmvc.*())"/>
          <!--切面-->
          <aop:advisor advice-ref="txadvice" pointcut-ref="pt"></aop:advisor>
      </aop:config>
      
    2. 注解
               <!-- 定义事务管理器 -->
       <bean id="transactionManager"
           class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
           <property name="dataSource" ref="dataSources"/>
       </bean>
       <!--开启注解事务管理-->
       <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
       <!--在需要事务管理的方法上添加注解 @Transactional-->
      
posted @ 2019-03-31 11:50  JaminYe  阅读(175)  评论(0编辑  收藏  举报