SSM-Spring

Spring

一,Spring框架是什么

  • Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
  • 2004年诞生,也叫Spring Framework,开源框架
  • 降低Java开发复杂度,解决业务逻辑层和其它层耦合的问题
    • 如何降低复杂度和实现解耦
      • 基于POJO轻量级和最小浸入性编程
      • 通过依赖注入和面向切面实现解耦
      • 基于切面和惯例进行声明式编程
      • 通过切面和模板减少样板式代码
  • 提供了一个底层容器和基础设施,可以和其他开源框架无缝集成
  • 其他版本介绍
    • SpringBoot
      • 快速开发脚手架
      • 基于SpringBoot可以开发单个微服务(小模块)
      • 约定大于配置
    • SpringCloud
      • 基于SpringBoot实现
      • 微服务整合
    • 学习上面需要掌握Spring,SpringMVC

二,优缺点

  1. 优点
    • 方便解耦,将所有对象的创建和依赖关系的维护交给Spring
    • AOP,支持面向切面编程
    • 支持声明式事务
    • 支持Junit,注解测试
    • 扩展性强,便于整合其它框架
    • 封装Java API,简化API使用
  • 强大的向后兼容(可以用最新的版本)
    • 易用性强
  1. 缺点
    • Spring 大而全,不够精简
    • Spring 依赖反射,反射影响性能
    • 使用门槛高,学习有难度(配置繁琐)

三,组成部分和学习要点

  1. 组成和功能
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iJu9C00J-1636367556365)(D:\ycdl\JavaNote\笔记\img\Spring2.png)]
  • Spring Core: 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。
  • Spring Aspects : 该模块为与AspectJ的集成提供支持。
  • Spring AOP :提供了面向切面的编程实现。
  • Spring JDBC : Java数据库连接。
  • Spring JMS :Java消息服务。
  • Spring ORM : 用于支持Hibernate等ORM工具。
  • Spring Web : 为创建Web应用程序提供支持。
  • Spring Test : 提供了对 JUnit 和 TestNG 测试的支持。
  • 依赖关系
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XP6oImAz-1636367556372)(D:\ycdl\JavaNote\笔记\img\Spring.png)]
  • 各个部件的介绍
  1. 学习要点
    • IOC 控制反转 (重点)
    • AOP 面向切面编程 (重点)
    • 访问数据库
    • web应用
    • 集成外部组件

四,配置Spring开发环境

1. 首先需要下载Spring Framework
  • 去找Spring官网

  • 点击Projects 找到Spring Framework

  • 官方文档

  • git

  • maven坐标(如果用最大的,maven会将其他依赖都下载)

    • <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.3.5</version>
      </dependency>
      <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>5.3.5</version>
      </dependency>
      <dependency>
      <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
      </dependency>
      
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7tEjPmjr-1636367556374)(D:\ycdl\JavaNote\笔记\img\Spring3.png)]

2.写实现
  • dao层

  • package com.itcase.dao.impl;
    
    import com.itcase.dao.UserDao;
    
    public class mysqlImpl implements UserDao {
    
        public void save() {
            System.out.println("mysql start save....");
        }
    }
    
  • package com.itcase.dao.impl;
    
    import com.itcase.dao.UserDao;
    
    public class oracleImpl implements UserDao {
        public void save() {
            System.out.println("oracle save......");
        }
    }
    
  • service层

  • package com.itcase.service.impl;
    
    import com.itcase.dao.UserDao;
    import com.itcase.service.UserService;
    
    public class UserServiceImpl implements UserService {
    
        private UserDao userDao;
        //set 方法注入UserDao
        public void setUserDao(UserDao userDao){
            this.userDao = userDao;
        }
    
        public void save(){
            userDao.save();
        }
    }
    
    
3. 配置spring核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    id 随便起-->
    <bean id="userDao" class="com.itcase.dao.impl.mysqlImpl"></bean>
    <bean id="oracleImpl" class="com.itcase.dao.impl.oracleImpl"></bean>
   <!--    name如果set方法注入(setUserDao) 则是方法名(userDao) --> 
    <bean id="userService" class="com.itcase.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>
</beans>
4.测试环境
  @Test
    public void test01(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Application-config.xml");
        UserService service = (UserService) context.getBean("userService");
        service.save();
    }

五. 学习要点展开

1. IOC是什么
  • 情景 :需求改变必须改代码,接口实现增加,修改成本十分高,可扩展性差

  • private userDao userDao;
    public void setUserDao(UserDao userDao){
    	this.userDao = userDao;
    }
    
  • 实现将对象的创建权交给使用者

  • (对象可以自己创建,同样可以使用Spring的IOC,让Spring容器创建对象)控制反转

  • 降低了耦合(DI(依赖注入)实现)

  • 实现方式

    • XML
    • 注解
    • 自动装配
2.Spring配置文件
  • Bean

    • id Bean 的唯一标识
    • class 全限定类名
  • alias 别名

  • <alias name="userDao" alias="dao"></alias>
    
  • name

    • 作为别名 可以同时取多个别名
    • , 空格 ; 可作为分隔符
  • import 一般用于团队开发使用 可以将多个配置文件导入合并

3.依赖注入
  • 构造器注入

    • <constructor-arg name="username" value="admin"></constructor-arg>
    • 特别注意 如果存在有参构造请必须写无参构造,否则编译期报错
  • set方法注入(重点

    • 具体实现 参见Spring环境配置
    • 依赖:Bean 对象依赖于容器
    • 注入: Bean 对象的所有属性,由Spring 容器注入
  • 其他方式

    •     <bean id="address" class="com.itCase.pojo.Address">
              <property name="address" value="北京市朝阳区"/>
          </bean>
      
          <bean id="user" class="com.itCase.pojo.User">
      <!--        常量注入-->
              <property name="name" value="小明"/>
      <!--        对象注入-->
              <property name="address" ref="address"/>
      <!--        数组-->
              <property name="books">
                  <array>
                      <value>西游记</value>
                      <value>红楼梦</value>
                      <value>水浒传</value>
                  </array>
              </property>
      <!--        list注入-->
              <property name="hobby">
                  <list>
                      <value>打篮球</value>
                      <value>打游戏</value>
                      <value>游山玩水</value>
                  </list>
              </property>
      <!--        Map-->
              <property name="card">
                  <map>
                      <entry key="身份证" value="531222200008183723"/>
                      <entry key="学生卡" value="P191713256"/>
                      <entry key="银行卡" value="6213222000158686"/>
                  </map>
              </property>
      <!--        set-->
              <property name="game">
                  <set>
                      <value>LOL</value>
                      <value>BOB</value>
                      <value>COC</value>
                  </set>
              </property>
      <!--        null-->
              <property name="married">
                  <null/>
              </property>
      <!--        空字符-->
      <!--        <property name="married" value=""/>-->
      <!--        properties-->
              <property name="info">
                  <props>
                      <prop key="序号">1</prop>
                      <prop key="学号">P191713256</prop>
                      <prop key="性别"></prop>
                      <prop key="成绩">A</prop>
                  </props>
              </property>
          </bean>
      
    • 命名空间注入

    • <?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:p="http://www.springframework.org/schema/p"
             xmlns:c="http://www.springframework.org/schema/c"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
          <!--   xmlns:p="http://www.springframework.org/schema/p" -->
          <!--  p  命名空间注入 对应set注入-->
          <bean id="userInfo" class="com.itCase.pojo.UserInfo" p:name="小红" p:age="18"/>
      
      
          <bean id="user" class="com.itCase.pojo.User" p:address-ref="address"/>
          <!--    c 命名空间就是构造器注入-->
      <!--    <bean id="address" class="com.itCase.pojo.Address" p:address="小明"/>-->
          <bean id="address" class="com.itCase.pojo.Address" c:address="西安未央"/>
      </beans>
      
    • 作用相同的写法

      • UserInfo bean = context.getBean("userInfo",UserInfo.class);
      • UserInfo bean = (UserInfo)context.getBean("userInfo");
    • Bean 的作用域

      • 默认是单例的

      • <bean id="address" class="com.itCase.pojo.Address" c:address="西安未央" scope="prototype"/>
        

        1、singleton:只要id与该bean定义相匹配,则只会返回bean的同一实例。注意:Singleton作用域是Spring中的缺省作用域

        **2、prototype:**每次getBean() 都会给出一个新的实例

        web中的:

        **2、request:**在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。
        考虑下面bean定义:

        针对每次HTTP请求,Spring容器会根据loginAction bean定义创建一个全新的LoginAction bean实例, 且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态, 而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。 当处理请求结束,request作用域的bean实例将被销毁。
        **4、session:**在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
        考虑下面bean定义:

        针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例, 且该userPreferences bean仅在当前HTTP Session内有效。 与request作用域一样,你可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例, 将不会看到这些特定于某个HTTP Session的状态变化。 当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。
        **5、global session:**在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。
        考虑下面bean定义:

        global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。
        请注意:假如你在编写一个标准的基于Servlet的web应用,并且定义了一个或多个具有global session作用域的bean,系统会使用标准的HTTP Session作用域,并且不会引起任何错误。

4.自动装配
  • xml

    • 原始

    • <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      
          <bean id="cat" class="com.itCase.pojo.Cat"/>
          <bean id="Dog" class="com.itCase.pojo.Dog"/>
          <bean id="People" class="com.itCase.pojo.People">
              <property name="name" value="小米"/>
              <property name="cat" ref="cat"/>
              <property name="dog" ref="Dog"/>
          </bean>
      </beans>
      
    • autowire

    • 根据set方法后面的名字寻找(注意必须是首字母小写不然报错)

      <bean id="People" class="com.itCase.pojo.People" autowire="byName">
          <property name="name" value="小米"/>
      </bean>
      
    • byType

    • 根据Bean的类型,不过必须全局唯一(单例)

  • Java 注解

    • 注解比较推荐,jdk1.5 后支持

    • 注解使用

      • 导入约束

      • <?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:context="http://www.springframework.org/schema/context"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd">
        </beans> 
        
      • 配置支持

      • <context:annotation-config/>

    • @Autowired

    • @Autowired
      private Cat cat;
      @Autowired
      private Dog dog;
      
    • @Qualifier(value="dog")

      • 当有多个实例时指定一个实例
      • @Resource 根据类型匹配
    • 注解可以不用set

    • 注意@nullTable 允许 null

  • 隐式的自动装配重要

5.注解开发(推荐且重要)

Spring 4 之后使用注解必须导入 AOP 依赖

  • 前期配置

    • 组件扫描和注解生效配置

    • <?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:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd">
      <!--    组件扫描  扫描包下类的注解-->
          <context:component-scan base-package="com.itCase.pojo"/>
      <!--    注解生效-->
          <context:annotation-config/>
      </beans>
      
  • Bean

    • @Component("UserPojo") 表明被Spring管理,
    • <bean id="user" class="com.itCase.pojo.UserInfo"></bean> 作用一致
  • 属性注入

  •     @Value("Tom")
        private String name;
        @Value("1")
        private Integer id;
    
  • 衍生注解

    • 根MVC来标注
    • @Component 的扩展
      • dao @Repository
      • service @Service
      • Controller @Controller
      • 注意 不能上面标识重名
  • 作用域

    • @Scope("prototype")
  • xml最佳实践

    • xml适用于所有的场合
    • 注解 不是自己的类使用不了,维护复杂
    • xml 管理Bean
    • 注解 属性注入
    • 注意 让注解生效
  • 完全注解配置

    • Spring 4 SpringBoot 中使用,建议注解

    • 使用步骤

      • 搭建MVC层接口与实现类

      • 使用 config.java (Spring 核心配置类) 替代原有的 Application-config.xml

      • //表明这个类被Spring管理
        @Configuration
        //组件扫描
        @ComponentScan("com.itCase")
        
        public class MyConfig {
        
            //非自定义的类
            @Bean("user")
            @Scope("prototype")
            public User getUser(){
                return new User();
            }
        
            //Bean的初始化方法
            @PostConstruct
            public void init(){
                System.out.println("初始化开始了");
            }
        
            //Bean的销毁方法
            @PreDestroy
            public void destroy(){
                System.out.println("Bean被销毁了");
            }
        }
        
      • 使用注解将接口实现类放进Spring容器

        • web @Controller("userController")

        • dao @Repository("userDao")

        • service

        • //使用注解 将本类放入容器
          @Service("userService")
          public class UserServiceImpl implements UserService {
          
          
              private UserDao userDao;
          
              //如果用这@Service("userService")
              //就不能@Autowired @Qualifier("userDao") 变量注入 只构造和set注入
              @Autowired
              @Qualifier("userDao")
              public void setUserDao(UserDao userDao){
                  this.userDao = userDao;
              }
          //    public UserServiceImpl(){
          //
          //    }
          //    @Autowired
          //    public UserServiceImpl(UserDao userDao){
          //        this.userDao = userDao;
          //    }
          
              public void save(){
                  userDao.save();
              }
          
          }
          
      • 需要注意的是

        • 重要 自定义的类可以用上面的注解或者 @Component("UserPojo") 表明被Spring管理

        • 非自定义的类 则需要 Bean 标签实现注入Spring容器

        • 特别注意的遗留问题

          • @Service("userService") 使用此类标签

          • //如果用这@Service("userService")
            //就不能@Autowired @Qualifier("userDao") 变量注入 只构造和set注入
            @Autowired
            @Qualifier("userDao")
            
      • 外部资源的引入

        • XML文件引入

        • <context:property-placeholder location="classpath:Druid.properties"/>
             <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
             <property name="driverClassName" value="${jdbc.driverClassName}"></property>
                 <property name="url" value="${jdbc.url}"></property>
               <property name="username" value="${jdbc.username}"></property>
                 <property name="password" value="${jdbc.password}"></property>
           </bean>
          
        • Java注解引入

        • //   加载配置文件<context:property-placeholder location="classpath:Druid.properties"/>
          @PropertySource("classpath:Druid.properties")
          public class dataSource {
              //不同于xml
              //外部资源的引入的表达式 不能直接写需要注入
              @Value("${jdbc.driverClassName}")
              private String driver;
          
              @Value("${jdbc.url}")
              private String url;
          
              @Value("${jdbc.username}")
              private String username;
          
              @Value("${jdbc.password}")
              private String password;
          
              @Bean("data")
              public DruidDataSource getDataSource() {
                  DruidDataSource data = new DruidDataSource();
                  data.setDriverClassName(driver);
                  data.setUrl(url);
                  data.setUsername(username);
                  data.setPassword(password);
                  return data;
              }
          }
          
6. AOP 代理模式
  1. 静态代理
  • 加东西会写很多类
  1. 动态代理
  • 重要底层都是反射
  • 分类
    • 基于接口的(JDK动态代理)
    • 基于类的(cglib)
    • java (.class)
  • 关键类
    • Poxy , InvocationHandler
    • 重要方法invoke()

3.动态代理如何实现

  • 代理类实现
package com.itCase02;

import org.omg.CORBA.OBJ_ADAPTER;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态生成代理类
 */
public class ProxyInvocationHandler implements InvocationHandler {

    //获取要创建的类型
    private Object target;

        public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理类对象
    public Object getProxy(){
        return Proxy.newProxyInstance(ProxyInvocationHandler.class.getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    //处理代理实例
 @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        logStart(method.getName());
        Object invoke = method.invoke(target, args);
        logFinish(method.getName());
        return invoke;
    }

    //需要增强的功能
    public void logStart(String msg){
        System.out.println("[DEBUG]:---执行了"+msg+"方法---");
    }
    public void logFinish(String msg){
        System.out.println("[DEBUG]:-执行了"+msg+"方法完成--");
    }
}
  • test

       @Test
        public void daoTest02(){
            UserDao userDao = new UserDaoImpl();
            ProxyInvocationHandler handler = new ProxyInvocationHandler();
            handler.setTarget(userDao);
            UserDao proxy = (UserDao) handler.getProxy();
            proxy.add();
            proxy.query();
            proxy.delete();
            proxy.upData();
        }
    
7,AOP
  1. AOP Spring是什么有什么作用

    在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方
    式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个
    热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑
    的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高
    了开发的效率。

    1. AOP编程可不是Spring独有的,Spring只是支持AOP编程的框架之一,这一点非常重要,切勿搞反了关系

    2. AOP分两类

      1. 一类可以对方法的参数进行拦截,
      2. 一类是对方法进行拦截,SpringAOP属于后者,所以Spring的AOP是属于方法级的
    3. AOP作用

      1. 声明式事务
      2. 自定义切面
    4. 相关概念

      Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
      Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
      Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
      Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
      Target(目标对象):织入 Advice 的目标对象.。
      Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程

  2. Spring AOP 配置环境

    • Spring AOP 所需依赖

    • <dependency>
      	<groupId>org.aspectj</groupId>
      	<artifactId>aspectjweaver</artifactId>
          <version>1.8.7</version>
      </dependency>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-webmvc</artifactId>
           <version>5.2.13.RELEASE</version>
       </dependency>
      
       <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope> 
      </dependency>
      
    • 导入命名空间

    • xmlns:aop="http://www.springframework.org/schema/aop"
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      
    • 实现方式

      • 第一种

      • public class AfterLog implements AfterReturningAdvice {
        
            //returnValue 返回值
            @Override
            public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
                System.out.println("[DEBUG]->"+target.getClass().getName()+"->"+method.getName()+"执行了返回了->"+returnValue);
            }
        
        }
        
      • public class log implements MethodBeforeAdvice {
        
            /*
             * Method 方法
             * Object[] 参数
             * Object target  目标对象
             *
             */
            @Override
            public void before(Method method, Object[] args, Object target) throws Throwable {
                System.out.println("[DEBUG]->"+target.getClass().getName()+"的"+method.getName()+"执行了");
            }
        }
        
        
      • <bean id="userDao" class="com.itDuck.dao.impl.UserDaoImpl"/>
            <bean id="log" class="com.itDuck.log.log"/>
            <bean id="logAfter" class="com.itDuck.log.AfterLog"/>
        
        <!--aop第一种方式  配置 aop 命名空间 导入约束-->
            <aop:config>
        <!--    定义切点 -->
                <aop:pointcut id="pointcut" expression="execution(* com.itDuck.dao.impl.UserDaoImpl.*(..))"/>
                        通知: 即方法
                <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
                <aop:advisor advice-ref="logAfter" pointcut-ref="pointcut"/>
            </aop:config>
        
      • test

      • @Test
           public void UserDaoAddTest(){
               ApplicationContext context =
                       new ClassPathXmlApplicationContext("Application-config.xml");
               UserDao dao = context.getBean("userDao",UserDao.class);
               dao.add();
               dao.upData();
               dao.delete();
               dao.query();
           }
        
      • 第二种 不实现接口自定义类

      • public class Pointcut {
            public void start(){
                System.out.println("------启动-------");
            }
            public void finish(){
                System.out.println("--------完成----------");
            }
        }
        
      •     <bean id="diy" class="com.itDuck.diy.Pointcut"/>
            <aop:config>
        <!--        自定义切面-->
                <aop:aspect ref="diy">
        <!--            切入点:-->
                    <aop:pointcut id="pointcut" expression="execution(* com.itDuck.dao.impl.UserDaoImpl.*(..))"/>
        <!--            通知: 即方法-->
                    <aop:before method="start" pointcut-ref="pointcut"/>
                    <aop:after method="finish" pointcut-ref="pointcut"/>
                </aop:aspect>
            </aop:config>
        
      • 第三种方式 注解实现

      • @Component("APCut")
        @Aspect
        public class AnnotationPointCut {
            @Before("execution(* com.itDuck.dao.impl.UserDaoImpl.*(..))")
            public void Before(){
                System.out.println("------------start-----------");
            }
        
            @AfterReturning("execution(* com.itDuck.dao.impl.UserDaoImpl.*(..))")
            public void After(){
                System.out.println("-------------end-----------");
            }
        
            @Around("execution(* com.itDuck.dao.impl.UserDaoImpl.*(..))")
            public void around(ProceedingJoinPoint jp) throws Throwable {
                System.out.println("---------环绕前----------");
                //日志打印签名
                Signature signature = jp.getSignature();
                System.out.println(signature);
                //方法执行
                jp.proceed();
                System.out.println("---------环绕后----------");
            }
        }
        
8.Spring整合MyBatis
  1. 实现步骤

    1. 导入maven依赖

      <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-webmvc</artifactId>
                  <version>5.2.13.RELEASE</version>
              </dependency>
      
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.12</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-test</artifactId>
                  <version>5.2.13.RELEASE</version>
              </dependency>
      
      
              <!--    spring jdbc -->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-jdbc</artifactId>
                  <version>5.2.13.RELEASE</version>
              </dependency>
      
              <!--Spring事务提交 -->
      
              <!--    mybatis-->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.4.5</version>
              </dependency>
      
              <!--    mysql driver-->
      
              <!--    日志-->
              <dependency>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
                  <version>1.2.17</version>
              </dependency>
      
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>5.1.23</version>
              </dependency>
      
              <!--    日志-->
              <!--  druid数据源  -->
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>druid</artifactId>
                  <version>1.1.23</version>
              </dependency>
              <!--Spring-jdbc-->
              <!-- aop依赖-->
              <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjweaver</artifactId>
                  <version>1.8.7</version>
              </dependency>
              <!--mybatis 整合Spring -->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis-spring</artifactId>
                  <version>2.0.1</version>
              </dependency>
      <!-- pojo  lombok     -->
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>1.18.12</version>
                  <scope>provided</scope>
              </dependency>
      
    2. 配置让xml被识别

      <!--配置识别xml 配置文件-->
              <resources>
                  <resource>
                      <directory>src/main/java</directory>
                      <includes>
                          <include>**/*.properties</include>
                          <include>**/*.xml</include>
                      </includes>
                      <filtering>true</filtering>
                  </resource>
                  <resource>
                      <directory>src/main/resources</directory>
                      <includes>
                          <include>**/*.properties</include>
                          <include>**/*.xml</include>
                      </includes>
                      <filtering>true</filtering>
                  </resource>
              </resources>
      
    3. 按照搭建mybatis的步骤,调通实现查询

      1. 主配置文件

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>
        
            <!--    引入jdbc配置文件-->
            <properties resource="druid.properties"/>
        
            <settings>
                <setting name="logImpl" value="LOG4J"/>
            </settings>
        
            <typeAliases>
                <typeAlias type="com.itCast.pojo.UserPojo" alias="user"/>
            </typeAliases>
        
        <!--    <environments default="development">-->
        <!--        <environment id="development">-->
        <!--            <transactionManager type="JDBC"/>-->
        <!--            <dataSource type="POOLED">-->
        <!--                <property name="driver" value="${driverClassName}"/>-->
        <!--                <property name="url" value="${jdbc.url}"/>-->
        <!--                <property name="username" value="${jdbc.username}"/>-->
        <!--                <property name="password" value="${jdbc.password}"/>-->
        <!--            </dataSource>-->
        <!--        </environment>-->
        <!--    </environments>-->
        <!--    <mappers>-->
        <!--        <mapper resource="com/itCast/mapper/UserMapper.xml"/>-->
        <!--    </mappers>-->
        
        </configuration>
        
      2. UserMapper.xml 数据库映射文件

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper
                PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        
        <mapper namespace="com.itCast.mapper.UserMapper">
            <select id="getUserList" resultType="com.itCast.pojo.UserPojo">
                select * from user
             </select>
        </mapper>
        
      3. 特别注意

        • 数据源和JDBC配置 druid.properties 问题
          • url -> jdbc.url
          • username -> jdbc.username
          • password -> jdbc.password
          • 写成左边的话会出现错误:调用系统的用户对象
        • 整合Spring时在主配置文件
          • 请注释掉mybatis当中与Spring重复的配置否则会报错
          • 例如:environmentsmappers
    4. 编写配置文件

      1. Spring主配置文件

        <?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"
               xmlns:context="http://www.springframework.org/schema/context"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!--    组件扫描  扫描包下类的注解-->
        <!--     <context:component-scan base-package="com.itCast"/>-->
        <!--    注解生效-->
        <!--    <context:annotation-config/>-->
        
            <import resource="classpath:spring-dao.xml"/>
        <!--  第一种方式  注册impl-->
            <bean id="userMapper" class="com.itCast.mapper.impl.UserMapperImpl">
                <property name="sqlSessionTemplate" ref="sqlSession"/>
            </bean>
        <!--   第二种方式 不用自己写sqlSessionFactory sqlSession-->
            <bean id="userMapper02" class="com.itCast.mapper.impl.UserMapper02">
                <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
            </bean>
        <!--    <aop:aspectj-autoproxy/>-->
        
        </beans>
        
      2. Spring-Dao 配置文件

        <?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"
               xmlns:context="http://www.springframework.org/schema/context"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop.xsd">
        
            <!--    引入外部资源-->
            <context:property-placeholder location="druid.properties"/>
            <!--  配置druid数据源 druid.properties-->
            <!--  注意 druid.properties 当中username password 写成jdbc.username jdbc.password 不然会报错-->
            <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
                <property name="driverClassName" value="${driverClassName}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </bean>
        
            <!--    注册mybatis所用对象-->
            <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
                <property name="dataSource" ref="dataSource"/>
                <property name="configLocation" value="classpath:mybatis-config.xml"/>
                <property name="mapperLocations" value="classpath:com/itCast/mapper/UserMapper.xml"/>
            </bean>
        
            <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
                <constructor-arg index="0" ref="sqlSessionFactory"/>
            </bean>
        
        </beans>
        
      3. 数据源和JDBC配置

        driverClassName=com.mysql.jdbc.Driver
        jdbc.url=jdbc:mysql://localhost:3306/stu_new_manager?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC&amp;rewriteBatchedStatements=true
        jdbc.username=root
        jdbc.password=123456
        initialSize=5
        maxActive=10
        maxWait=3000
        maxIdle=8
        minIdle=3
        
      4. 日志配置 LOG4J

        #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
        log4j.rootLogger=DEBUG,console,file
        
        #控制台输出的相关设置
        log4j.appender.console = org.apache.log4j.ConsoleAppender
        log4j.appender.console.Target = System.out
        log4j.appender.console.Threshold=DEBUG
        log4j.appender.console.layout = org.apache.log4j.PatternLayout
        log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
        
        #文件输出的相关设置
        log4j.appender.file = org.apache.log4j.RollingFileAppender
        log4j.appender.file.File=./log/kexing.log
        log4j.appender.file.MaxFileSize=10mb
        log4j.appender.file.Threshold=DEBUG
        log4j.appender.file.layout=org.apache.log4j.PatternLayout
        log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
        
        #日志输出级别
        log4j.logger.org.mybatis=DEBUG
        log4j.logger.java.sql=DEBUG
        log4j.logger.java.sql.Statement=DEBUG
        log4j.logger.java.sql.ResultSet=DEBUG
        log4j.logger.java.sql.PreparedStatement=DEBUG
        
      5. 特别注意

        1. 编写的两个Spring配置文件 ,需要在主配置文件中引入

        2. 注意整合时Spring 获取SqlSession的两个方式

          1. 不需要继承

            <!--    注册mybatis所用对象-->
                <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
                    <property name="dataSource" ref="dataSource"/>
                    <property name="configLocation" value="classpath:mybatis-config.xml"/>
                    <property name="mapperLocations" value="classpath:com/itCast/mapper/UserMapper.xml"/>
                </bean>
            
                <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
                    <constructor-arg index="0" ref="sqlSessionFactory"/>
                </bean>
            
            public class UserMapperImpl implements UserMapper {
            
                private SqlSessionTemplate sqlSessionTemplate;
            
                public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
                    this.sqlSessionTemplate = sqlSessionTemplate;
                }
            
                @Override
                public List<User> getUserList() {
                    UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
                    return mapper.getUserList();
                }
            }
            
            <!--  第一种方式  注册impl-->
                <bean id="userMapper" class="com.itCast.mapper.impl.UserMapperImpl">
                    <property name="sqlSessionTemplate" ref="sqlSession"/>
                </bean>
            
          2. 第二种方式 extends SqlSessionDaoSupport

            package com.itCast.mapper.impl;
            
            import com.itCast.mapper.UserMapper;
            import com.itCast.pojo.User;
            import org.mybatis.spring.support.SqlSessionDaoSupport;
            
            import java.util.List;
            
            public class UserMapper02 extends SqlSessionDaoSupport implements UserMapper {
                @Override
                public List<User> getUserList() {
                    return getSqlSession().getMapper(UserMapper.class).getUserList();
                }
            }
            
            
            <!--   第二种方式 不用自己写sqlSession-->
                <bean id="userMapper02" class="com.itCast.mapper.impl.UserMapper02">
                    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
                </bean>
            
        3. 配置文件 properties 中命名问题 ,借鉴 按照搭建mybatis的步骤,调通实现查询 -> 3.特别注意

    5. 最后的步骤

      1. 除去mybatis的实现外还需要编写UserMapper.interface 的实现类

      2. public class UserMapper02 extends SqlSessionDaoSupport implements UserMapper {
            @Override
            public List<User> getUserList() {
                return getSqlSession().getMapper(UserMapper.class).getUserList();
            }
        }
        
      3. 测试类

      4. @Test
         public void getUserListTest1(){
             ApplicationContext context = new ClassPathXmlApplicationContext("Application-config.xml");
             UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
             List<User> list = userMapper.getUserList();
             for (User user : list) {
                 System.out.println(user);
             }
         }
        
9.声明式事务
  1. 事务解释

    • 同一组业务看成一个业务,全部成功或者全部失败
    • 开发中十分重要确保完整性和一致性
  2. 事务的ACID原则

    • 原子性
    • 一致性
    • 隔离性
      • 多个事务访问同一资源时,防止数据损坏
    • 持久性
      • 事务一旦提交,就会被持久保存
  3. 如何实现

    1. 配置

       <!--  spring aop 配置声明式事务  -->
          <bean id="transaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"/>
          </bean>
      <!--结合aop实现事务-->
      <!--    配置事务通知-->
          <tx:advice id="txAction" transaction-manager="transaction">
              <tx:attributes>
                  <tx:method name="add" propagation="REQUIRED"/>
                  <tx:method name="delete" propagation="REQUIRED"/>
                  <tx:method name="query" propagation="REQUIRED"/>
                  <tx:method name="*" propagation="REQUIRED"/>
              </tx:attributes>
          </tx:advice>
      <!--aop-->
          <aop:config>
              <aop:pointcut id="txPointcut" expression="execution(* com.itCast.mapper.*.*(..))"/>
              <aop:advisor advice-ref="txAction" pointcut-ref="txPointcut"/>
          </aop:config>
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值