栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring5 学习

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring5 学习

Spring5 学习 简介

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

导包


    org.springframework
    spring-webmvc
    5.3.10





    org.springframework
    spring-jdbc
    5.3.10


优点
  • Spring是一个开源的免费的框架(容器)!
  • Spring是一个轻量级的、非入侵式的框架!
  • 控制反转(IOC)面向切面编程(AOP)!
  • 支持事务的处理,对框架整合的支持!
Spring组成及扩展 组成

ORM 对象关系映射

现代化的开发:基于spring的开发

springboot:

  • 一个快速开发的脚手架:
  • 基于SpringBoot 可以快速的开发单个微服务
  • 约定大于配置

SpringCloud

  • SpringCloud是基于SpringBoot 实现的

弊端: 违背了 当初的理念,需要配置大量的东西

IOC理论推导

创建UserDao接口,以减少代码;系统的耦合性降低

IOC本质

控制反转(inversion of control), 是一种设计思想,DI(dependency injection依赖注入)是IOC的一种方法。未使用IOC的程序中,我们使用面向对象编程,对象的创建和对象之间的依赖关系完全硬编码在程序中,对象的创建是由程序自己控制的。控制反转就是将对象的创建转移给了第三方.IOC就我认为是:获得依赖对象的方式反转了

DI只是实现IOC的一种方法

IOC是Spring框架的核心内容, 使用了多种方式完美的实现了IOC,xml配置与注解形式,新版本的spring也可以零配置实现IOC

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

Hello Spring
Spring xml  配置


        

对象是由Spring创建的,对象的属性是由Spring 设置的 这个过程就叫做控制反转

具体使用

ref 引用Spring容器中已经创建好的对象

value是所创建的对象的具体的值

对象由Spring来创建 管理 和分配

IOC创建对象方式 使用构造器创建对象
  1. 使用无参构造器 创建对象

  2. 使用有参构造创建对象

    • 使用下标赋值法创建对象

        
              
          
      
    • 使用类型进行赋值

      
              
          
      
      但是这种方法不建议使用 当有多个参数类型相同时,容易出现错误
      
    • 直接通过参数名设置

      
              
          
      

在配置文件加载的时候,容器中管理的对象就已经初始化了

Spring配置说明 别名

改成什么都可以使用
Bean的配置 通过配置来实现IOC
   
        
   

    
import配置

一般用于团队开发,可以将多个配置文件导入合并为一个


DI 依赖注入环境

三种方式 构造器注入

构造器注入

constructor-arg 这种方式 就属于构造器注入

Set方式注入(重点) 要写 set方法

依赖注入:set注入

依赖:bean 对象的创建依赖于容器

注入:bean对象中的所有属性,由容器来注入

第一种:普通值注入 value


        

第二种: bean注入 使用 ref


第三种: 数组注入


            
                围城
                围城
                围城
                围城
            

第四种: list集合注入

   
            
                
                
                RAP
                打篮球
            
        

​ 第五种:map注入

 
            
                
                
            
        

第六种:set注入

  
            
                LOL
                COD
                王者
            
        

第七种:空值注入

 
            
                202031008010
                98
            
        
扩展方式注入

c命名和p命名空间注入方式

p命名空间

    


    
c命名空间

    

注意点:p命名空间和c命名空间 不可以直接使用 需要导入xml约束

xmlns:p="http://www.springframework.org/schema/p"  xmlns:c="http://www.springframework.org/schema/c"
Bean的作用域

默认的是单例模式 也可以显示的定义

单例模式 默认是单例模式

原型模式
 

原型模式会产生两个不同的对象,并且是每次get,都会产生一个新的对象

这里的get获取bean

其余的都是在web开发中会用到

自动装配bean
  • 自动装配是满足bean依赖的一种方式
  • Spring会在上下文中自动寻找,被自动给bean装配属性

在Spring中有三种装配方式

  1. 在xml中显示的配置
  2. 在Java中显示的进行配置
  3. 隐式的自动装配bean
ByName自动装配 通过名字来是实现自动装配

xml配置

 	
    
    
        
    

java测试代码

一个人 两个宠物 两个宠物只有方法的实现 没有成员变量

 @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        People people = context.getBean("people",People.class);
        System.out.println(people.getName());
        people.getCat().shut();
        people.getDog().shut();

    }
byType 通过类型查找
!--    ByTYpe 自动装配会自动在容器的上下文中查找 与自己的类型相同的beanId  但是它有弊端  必须得保证类型全局唯一-->
    
        
    

小结:

  1. byname的时候,需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一样
  2. bytype的时候,需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一样
使用注解进行自动装配

jdk1.5支持的注解 Spring2.5 支持的注解

使用注解须知:

  1. 导入约束: context约束
  2. 配置注解的支持: context:annotation-config/


    
    

@Autowired自动装配注解
@Autowired
可以直接在属性上使用  也可以在set方法上使用
使用@Autowired 我们可以不用写set方法了 前提是你这个自动装配的属性在IOC(Spring) 容器中是存在的,且命名符合ByName

@nullable 字段标记了这个注解,说明这个字段可以为null;

public void setName(@Nullable String name) {
        this.name = name;
 }

使用nullable标记了这个注解 说明这个字段可以为空  并且还不会报错

@Autowired自动装配注解参数设置

 注解装配在属性上

@Autowired(required = false)
    private Dog dog;
required = false 将required设置为空 说明这个对象可以为null,否则不允许为空

@Qualifier 在id名和class名都不相同时。可以结合使用Qualifier 来实现自动装配 Qualifier 中有一个参数为value 专门用来解决这个问题

@Resource Java注解
@Resource
private Dog dog;

这个注解先通过 名字(name)进行查找 名字查找不到 通过类型进行查找 如果名字和类型都查找不到,才会报错

 @Resource(name = "dog")

也可以通过指定名字进行注解

小结

@Resource和@Autowired 之间的区别

  • 都是用来自动装配的,都可以放在字段上
  • @Autowired 是通过byType的方式实现的,而且必须要求这个对象存在 通过类型来实现
  • @Resource 默认通过byName 的方式来实现,如果找不到名字,则通过byTYpe来实现,如果两个都找不到,则进行报错
    通过名字来实现
  • 执行顺序不同,@Autowired 通过byType来实现
Spring注解开发

在Spring4之后,如果想使用注解进行开发,必须导入aop的包

Component

组件 使用方法为放到类上 说明这个类被Spring管理了 就是bean

属性注入

@Value("海洪健")
public String name;
通过value可以设置值 简单的可以使用 复杂的推荐使用配置文件

衍生的注解

在web开发中每一层都有自己的注解

dao @Repository
controller  @Controller
service @service
bean  @Component
这四个注解的功能都是一样的  都是将某个类注册到Spring容器中

xml与注解之间的区别

  • xml更加的万能,适用与任何的场合!维护也相对简单。
  • 注解 不是自己的类使用不了,维护相对的复杂!

xml与注解的最佳实现:

  • xml只用来管理
  • 注解只负责完成属性的注入;
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持。
使用JavaConfig实现配置
User类
package com.hai.spring.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
// 自动注解
@Component
public class User {
    private String name;

    public User() {
    }


    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    @Value("海洪健")
    public void setName(String name) {
        this.name = name;
    }
}
config 类
    
// @Configuration  @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
    // 要求
    //@Configuration不可以是final类型;
	//@Configuration不可以是匿名类;
	//嵌套的configuration必须是静态类。
package com.hai.spring.config;

import com.hai.spring.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 获取新的用户 这个注解用于定义配置类 可替换 xml配置文件
@Configuration
public class MyConfig {
    @Bean
    public User getUser() {
        return new User();
    }
}
测试类
package com.hai.test;

import com.hai.spring.config.MyConfig;
import com.hai.spring.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestOne {
    // context 获取Spring的上下文对象
    // 获取ApplicationContext 拿到Spring容器
    // 我们的对象都在Spring进行管理了,如果要使用,直接取出来就可以了
    @Test
    public void test() {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        User user  = (User) context.getBean("getUser");
        System.out.println(user.getName());
    }
}
代理模式

为什么要学习代理模式? 因为代理模式就是Spring-Aop 的底层

SpringAop 和 SpringMvc重点 公司都会问

静态代理模式

代理就是帮我做事情 和中介查不多

角色分析:

抽象角色: 一般会用接口或者是抽象类来解决

真实角色: 被代理的角色

代理角色: 代理真实角色,代理真实角色后,我们一般会做一些附属操作

客户:访问代理角色的人

代理模式的好处:

  • 可以使真实角色的操作更加的纯粹。不用去关心一些公共的事务
  • 公共事务交给代理角色。实现了业务的分工
  • 公共业务发生扩展时,方便集中管理

缺点:

  • 一个真实的角色就会产生一个代理角色,这样会导致代码量翻倍。开发效率会变低。解决这个问题的方法就是动态代理

代理的步骤:

  1. 租房子接口

    public class Rent {
        public void rent();
    }
    
  2. 房东租房子 实现接口

    public class host implements Rent{
        public void rent() {
            System.out.println("我要租房子!");
        }
    }
    
  3. 代理待租房子 有自己的一些方法

    public class dali {
        private Host host;
        public dali(){}
        public dali(Host host) {
            this.host = host;
        }
        public void rent() {
            host.rent();
        }
    }
    
  4. 客户端访问租房子

    public class customer {
        @Test
        public void test() {
            Host host = new Host();
            Dali dali = new Dali(host);
            dali.rent();
        }
    }
    

    静态代理的解决方法就是动态代理

    输出一个日志 我们可以通过增加 代理的方式来实现 尽量的去增加东西 而不是删除东西

动态代理详解

动态代理运用的是反射这个技术

  • 动态代理和静态代理的角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的!
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
  • 基于接口— JDK动态代理 【我们在这里使用】
  • 基于类: cglib
  • java 字节码实现 : Javasist

需要了解两个类: Proxy : 代理 ,InvocationHandler:调用处理

InvocationHandler

动态代理的好处

  • 可以使真实角色的操作更加的纯粹。不用去关心一些公共的事务
  • 公共事务交给代理角色。实现了业务的分工
  • 公共业务发生扩展时,方便集中管理
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可。
AOP 什么是AOP

导包

使用SpringAop的时候,我们必须得导包

 
       org.aspectj
       aspectjweaver
       1.9.7
 

AOP的配置文件头




AOP的实现流程

ApplicationContext 文件




    
    
    
    

    
    
    
        
        


        
        
    

接口

package com.hai.spring.service;

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}


public class UserServiceImpl implements UserService{

    @Override
    public void add() {
        System.out.println("增加了一个用户!");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户!");
    }

    @Override
    public void update() {
        System.out.println("更改了一个用户!");
    }

    @Override
    public void query() {
        System.out.println("查询了一个用户!");
    }
}
执行前
package com.hai.spring.log;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class BeforeLog implements MethodBeforeAdvice {

    // method: 要执行的目标对象的方法
    // args: 参数
    // target: 目标对象
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了");
    }
}
执行后
package com.hai.spring.log;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterLog implements AfterReturningAdvice {

    // returnValue 执行后具有反回值 这个值就是返回值
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了" + method.getName() + "方法!");
    }
}
AOP 实现方法二

方法二:使用自定义类来实现 AOP

自定义切入点 切入点中放通知

主要是切面定义

    
    

        
        
            
             // execution中放的是程序要执行的位置
            

            
            
        
    
package com.hai.spring.diy;

public class DiyPointCut {
    public void before() {
        System.out.println("========方法执行前==========");
    }
    public void after() {
        System.out.println("========方法执行后==========");
    }
}
test 测试类
public class TestOne {
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        // 因为动态代理代理的是一个接口 不是一个类 所以我们要使用接口
        UserService userService = context.getBean("userService",UserService.class);
        userService.add();
    }
}
注解实现AOP
    


    
@Aspect
public class AnnocationPointcut {

    @Before("execution(* com.hai.spring.service.UserServiceImpl.*(..))")
    public void before() {
        System.out.println("开始前!");
    }
    @After("execution(* com.hai.spring.service.UserServiceImpl.*(..))")
    public void after() {
        System.out.println("开始后!");
    }
    @Around("execution(* com.hai.spring.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("环绕前!");
        Object object = jp.proceed();
        System.out.println("环绕后!");
    }
}
回顾Mybatis
mybatis 核心配置文件




    
    
        
    
    
        
            
            
                
                
                
                
            
        
    
    
        
        
    
    
        
        
        
    

mappper配置



    
        
        
        
    
    

测试
package com.hai.test;

import com.hai.spring.mapper.UserMapper;
import com.hai.spring.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.List;

public class TestOne {
    private SqlSession sqlSession;
    private UserMapper userMapper;

    @Before
    public void before() throws IOException {
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        sqlSession = factory.openSession();
    }
    @Test
    public void getUser() {
        userMapper = sqlSession.getMapper(UserMapper.class);
        List list =  userMapper.getUser();
        for (User user : list) {
            System.out.println("user = " + user );
        }
    }
    @After
    public void after() {
        sqlSession.close();
    }

}
Mybatis 与 Spring 整合 方法一

template 模板

整合数据源 SqlSessionFactory SqlSessionTemplat





    
        
        
        
        
    

    
    
        
        
        
        
        
    

    
        
        
    

    
        
    

创建实现类 实现mybatis 所作的工作

package com.hai.spring.mapper;

import com.hai.spring.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class UserMapperImpl implements UserMapper{

    ///  我们的所有操作 都将使用 SqlSessiontemplate 来做
    private SqlSessionTemplate sqlSessionTemplate;

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    @Override
    public List getUser() {
        UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
        return userMapper.getUser();
    }
}

测试实现类

package com.hai.test;

import com.hai.spring.mapper.UserMapper;
import com.hai.spring.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class TestTwo {
    @Test
    public void test() {
        // 通过application上下文拿到  spring 容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConText.xml");
        UserMapper userMapper = context.getBean("userMapper",UserMapper.class);
        List list = userMapper.getUser();
        for (User user : list) {
            System.out.println("user =" + user );
        }
    }
}
方法二:
package com.hai.spring.mapper;

import com.hai.spring.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserMapperTwo extends SqlSessionDaoSupport implements UserMapper {

    @Override
    public List getUser() {
        SqlSession sqlSession = getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        return userMapper.getUser();
    }
}

        

方式二只需要配置 SqlSessionFactory 不需要配置别的

事务回顾

把一组事务当成一个事务来做,要么都成功 要么都失败

事务再项目开发中 十分的重要 涉及到数据的一致性问题 不能马虎

确保完整性和一致性

事务的ACID 原则
1. 原子性
   2. 一致性
   3. 隔离性: 多个事务之间互不干扰 为了保护数据
   4. 持久性  事务一旦提交 无论系统发生什么事情  结果都不会被更改 被持久化的保存了
Spring声明式事务

七种配置事务的传播特性的方法

事务需要我们手动的在xml文件中配置
我们需要手动开启事务
配置切入点 在切入点中插入事务

        
            
        



        


            
                
                
                
                
                
            
        


        
            
            
        
总结

重点是理解思想

笔记持续完善

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324590.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号