Spring-IOC学习

spring快速入门

本文参照狂神的视频编写https://www.bilibili.com/video/BV1WE411d7Dv?p=2

在此特别感谢狂神陪伴我度过无聊的2020的上半年。

maven仓库:



    org.springframework
    spring-webmvc
    5.2.4.RELEASE



    org.springframework
    spring-jdbc
    5.2.4.RELEASE

spring 的优点:

  • spring是一个免费的开源框架(容器)
  • spring是一个轻量级的,非入侵的框架
  • 控制反转(IOC)面向切面的编程(AOP)
  • 支持事务处理,对框架整合的支持

Spring就是一个轻量级,非入侵的控制反转(IOC)和面向切面(AOP)的框架!!

Spring Boot-构建一切

Spring Cloud-协调一切

Spring Cloud Date Flow-连接一切

spring.png

1.IOC理论推导

看代码略

对象的创建由用户创建,低层代码中不写明确的实现类。

2.IOC本质

控制反转:是一种设计思想,DI(依赖注入是实现IOC的一种方式)。

  • 控制反转:一种通过描述xml文件或注解,并通过第三方去产生或者获取特点对象的方式。

  • 在spring中控制反转就是IOC容器,其实现方式就是依赖注入。

3.hello Spring




      
        
    

    
        
    

    


IOC创建bean的两种方式:

  1. 无参构造

    • 先使用无参构造器创建出对象

    • 再使用set方法将对于的值一 一赋值进去

    结论:使用无惨构造就一定要有 无参构造器和set方法

    
            
    
    

property:属性
ref:对象
value:值

  1. 有参构造

    • 有参构造在创建对象的时候就将值赋值进去,无需set方法

​ 结论:使用无惨构造就一定要有 有参构造器

有参构造的方法:

  1. 下标赋值

    
        
           
            
        
    
  2. 类型赋值(不建议使用)

    
        
            
            
        
    
  3. 参数名(掌握)

    
        
            
            
        
    

IOC容器在创建对象的时候会把容器中的所有的对象都创建出来。(是不是单利模式蛤)

spring这个容器类似于婚介网站!!
只会创建一个实例

4.spring配置说明

4.1别名


    

4.2Bean的配置


    
       
        
    

id:唯一标识

class:全类名:报名+类名

name 也可以取别名,并且可以取多个别名 分割符可以为:1. 空格 2. 逗号 3. 分号

4.3 import


将不同的xml文件导入,很智能,自动寻找需要的bean文件

5.DI依赖注入

1.构造器注入

​ 如上文所述

2.set方式注入

依赖注入

  • 依赖:bean的创建是依赖于spring容器来创建的。
  • 注入:bean的参数注入是由set方法来注入的。

Student 类

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List hobbys;
    private Map card;
    private Set game;
    private String wife;
    private Properties info;
}

xml文件注入

 
        
        
        
            
                红楼梦
                水浒传
                三国演义
            
        
        
            
                唱跳
                篮球
                rap
            
        
        
            
               
               
            
        
        
            
                刀塔
                lol
            
        
        
            
                summer
            
        
        
            
        
    

3.其他拓展注入

  • p 命名空间

    约束:

    xmlns:p="http://www.springframework.org/schema/p"     
    

    使用:

    
    
  • c 命名空间

    约束:

     xmlns:c="http://www.springframework.org/schema/c"
    

    使用:

    
    

6.Bean Scops

单利模式(singleton):


原型模式(prototype):


7.Bean的自动装配

开启自动装配之后,spring会在beans上下文中自动去寻找所需的类型进行装配。

主要是一个类中有其他类需要注入其他类才可以完成注入的情形。

1.autowire



2.使用注解实现自动装配

  • 开启支持注解

    
    
  • 将所需的bean在xml文件中配置

    
    
    
    
  • 在对应的类中加入注解

    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
    

这样就可以实现自动注入了。

三种注解:

  1. @Autowired(基本都是这个)
    对应autowire="byName"

  2. @Qualifier
    对应autowire="byType"

  3. @Resource
    java中的原生注解,功能强大,具有byName和byType两个功
    先通过名字查找,再通过类型查找,都找不到则报错。

8.注解开发:

上述都为简化bean的配置的方法,那么如何做到最少配置和0配置呢?

那么就需要我们使用注解进行开发了。

1.最少配置

  • 开启扫描包

    
    

    spring 会自动的去扫描这个包下面的所有类,带有@Component注解的类spring就会在beans中自动创建。

    注意:

    
    
    
  • 在类上加@Component

    @Component
    public class User {
        @Value("summer")
        private String name;
        private int age;
        @Autowired
        private Dog dog;
        @Autowired
        private Cat cat;
    }
    

补充:

@Component的作用相当于:

 

@Autowired的作用相当于

 

@Component的衍生注解:

  • @Repository(dao层)

  • @Service(service层)

  • @Controller(controller层)

    @Value()
    简单的注入可以使用@Value()进行赋值

    复杂的DI注入还是使用配置文件

2. 0配置文件@Bean and @Configuration

本质就是将xml 文件变成了java类(好处就是更加的灵活)

  • 写一个配置类

    @Configuration
    @ComponentScan("com.summer.pojo")
    public class appconfig {
        @Bean
        public User user(){
            return new User();
        }
    }
    

补充:

1.加上@Configuration相当于



spring就会把这个类当成一个配置文件处理



spring就会把这个类当成一个配置文件处理

2.加上@Bean相当于


2.加上@Bean相当于


3.加上@ComponentScan("com.summer.pojo")相当于


4.方法名就是id(首字母小写)

5.返回值就是class

9.代理模式:

  1. 接口
  2. 真实角色
  3. 代理角色
  4. 客户端访问代理角色
    静态代理:

动态代理:1.基于接口2.基于类的动态代理

  • 基于接口:JDK动态代理
  • 基于类:cglib
  • java字节码实现:javasist

了解两个类:

  • Proxy:代理
  • Invocationhandler: 调用处理程序

10.spring实现AOP

注意点:动态代理代理的是一类接口

环境搭建

  • UserServer
public interface UserServer {
    void add();
    void delete();
    void update();
    void select();
}

  • UserServerImpl
public class UserServerImpl implements UserServer {
    public void add() {
        System.out.println("add");
    }

    public void delete() {
        System.out.println("delete");
    }

    public void update() {
        System.out.println("update");
    }

    public void select() {
        System.out.println("select");
    }
}

方式一:使用Spring的API接口

  • Log类
public interface Log {
    void message();
}
  • BeforeLog
public class BeforeLog implements Log, MethodBeforeAdvice {
    public void message() {
        System.out.println("BeforeLog");
    }

    public void before(Method method, Object[] objects, Object o) throws Throwable {
        message();
    }
}
  • AfterLog
public class AfterLog implements AfterReturningAdvice,Log {

    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        message();
    }

    public void message() {
        System.out.println("AfterLog");
    }
}
  • applicationcontext.xml



    
    
    
    

    
        
        
        
    


  • 测试
public class mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");
        UserServer userServer = (UserServer) context.getBean("userServer");
        userServer.add();
    }
}

方式二: 使用自定义接口来实现AOP

  • DiyPointCut
public class DiyPointCut {

    public void before(){
        System.out.println("before");
    }
    public void after(){
        System.out.println("after");
    }
}
  • applicationcontext.xml



    
    

    
        
            
            
            
        
    

  • 测试
public class mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");
        UserServer userServer = (UserServer) context.getBean("userServer");
        userServer.add();
    }
}

方式三:使用注解实现

  • AnnotationPointCut
public class AnnotationPointCut {
    @Before("execution(* com.summer.server.UserServerImpl.*(..))")
   public void before(){
       System.out.println("before");
   }

    @After("execution(* com.summer.server.UserServerImpl.*(..))")
   public void after(){
       System.out.println("after");
   }
}
  • applicationcontext.xml



    
    
      
    


  • 测试
public class mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");
        UserServer userServer = (UserServer) context.getBean("userServer");
        userServer.add();
    }
}

12.整合Mybatis

1.导入相关jar包

  1. log4j
  2. junit
  3. mybatis
  4. mysql-connection-java
  5. spring-webmvc
  6. spring-jdbc
  7. aspectj
  8. mybatis-spring
  9. lombok
   
        
        
            log4j
            log4j
            1.2.17
        

        
            junit
            junit
            4.12
        

        
            org.mybatis
            mybatis
            3.5.2
        


        
            mysql
            mysql-connector-java
            5.1.47
        

        
            org.springframework
            spring-webmvc
            5.1.10.RELEASE
        

        
            org.springframework
            spring-jdbc
            5.1.10.RELEASE
        

        
        
            org.aspectj
            aspectjweaver
            1.9.4
        

        
            org.mybatis
            mybatis-spring
            2.0.2
        

        
        
            org.projectlombok
            lombok
            1.18.8
            provided
        

    

原来编写mybatis的方式:

  1. 编写实体类:Student

    package com.summer.pojo;
    
    import java.util.Date;
    
    public class Student {
        private int id;
        private String name;
        private String unick;
        private String ugender;
        private String upass;
        private Date addtime;
        //get set  toString
    }
    
    
  1. 编写核心配置文件:

    
    
    
      
        
          
          
            
            
            
            
          
        
      
      
        
      
    
    
  1. 编写接口

    public interface StudentDaoMapper {
        public List selectAll();
    }
    
  1. 编写Mapper.xml文件

    
    
    
        
    
    
  1. 测试

     @Test
     public void test01() throws IOException {
         String res = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(res);
         
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
         
        UserDaoMapper mapper = sqlSession.getMapper(UserDaoMapper.class);
        List list = mapper.selectAll();
        System.out.println(list);
     }
    

13.使用spring整合mybatis

我们在测试类中看见

String res = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(res);     
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);

我们需要在代码中手动创建SqlSessionFactory和SqlSession

现在我们可以通过spring的IOC容器来帮助我们自动创建他们

整合步骤:

pojo依然使用上面的student

使用SqlSessionTemplate

1.编写一个spring-dao.xml




    
        
        
        
    

    
        
        
        
        
    

    
        
    

2.编写实现类

public class StudentDaoImpl implements StudentDaoMapper{

    private SqlSessionTemplate sqlSession;

    public StudentDaoImpl(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    public List selectAll() {
        StudentDaoMapper mapper = sqlSession.getMapper(StudentDaoMapper.class);
        return mapper.selectAll();
    }
}

代码可以看到我们只是在原来的基础上多封装了一层,每次调用的时候不需要sqlsession了,而是在基础代码中已经使用过了sqlsession。

3.编写ApplicationContext.xml将bean交给IOC



    
    
        
    

4.测试

    @Test
    public void test01() throws IOException {
       ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        StudentDaoMapper userMapper = context.getBean("studentMapper", StudentDaoMapper.class);
        List list = userMapper.selectAll();
        System.out.println(list);
    }

使用SqlSessionDaoSupport

我们在实现类上面继承一个SqlSessionDaoSupport

我们就可以不用在spring-dao.xml 中创建SqlSessionTemplate

而我们在创建这个实现类的时候要将sqlSessionFactory丢到这个实现类中

因为我们继承了SqlSessionDaoSupport,而这个SqlSessionDaoSupport在他的实现类中使用sqlSessionFactory获得了SqlSessionTemplate。并用getSqlSession方法,返回SqlSessionTemplate。

1.StudentDaoImpl2

public class StudentDaoImpl2 extends SqlSessionDaoSupport implements StudentDaoMapper {
    public List selectAll() {
        return getSqlSession().getMapper(StudentDaoMapper.class).selectAll();
    }
}

2.ApplicationContext.xml



    
    
        
    

14.声明式事务

1.回顾事务

  • 要么都成功,要么都失败!
  • 保证数据的一致性

2.事务的ACID原则

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

3.spring 开启事务的管理

  • 编程式事务(在代码中添加事务)
  • 声明式事务(AOP)

配置事务:

​ 在spring-dao.xml 中开事务,并将事务使用aop横切进入代码中

    
    
        
    

     
        
         
             
         
     

    
    
     
        
        
    

补充:

spring 的配置文件




  


mybatis的配置文件







你可能感兴趣的:(Spring-IOC学习)