【Spring学习历程】---- 遇见狂神说课程笔记

【Spring学习历程】---- 遇见狂神说课程笔记,第1张

文章目录
  • Spring学习
      • 1、Spring组成
      • 2、IOC理论推导
      • 3、IOC创建对象的方式
        • 3.1使用无参构造创建,默认
        • 3.2使用有参构造创建
      • 4、Spring配置
        • 4.1别名
        • 4.2Bean的配置
      • 5、依赖注入
        • 5.1构造器注入
        • 5.2Set方式注入【重点】
        • 5.3拓展方式注入
        • 5.4bean的作用域
      • 6、Bean的自动装配
        • 6.1、测试
        • 6.2、ByName自动装配
        • 6.3、ByType自动装配
        • 6.4、 使用注解实现自动装配
      • 7、使用注解开发
        • 注解
      • 8、完全使用Java的方式配置Spring
      • 9、代理模式
        • 9.1、静态代理
        • 9.2、动态代理
      • 10、AOP
        • 10.1、AOP介绍
        • 10.2、使用Spring实现AOP
      • 11、整合Mybatis
        • 11.1、回忆Mybatis
      • 12、声明式事务
        • 1、回顾事务

Spring学习 1、Spring组成

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

大多是公司都在使用SpringBoot进行快速开发,学习Springboot的前提,就是完全掌握Spring以及SpringMVC,其承上启下的作用

弊端:发展太久了,违背了之前的理念,配置十分繁琐“配置地狱”

2、IOC理论推导

对象由Spring来创建,管理,装配

IOC(控制反转)的本质:是一种设计思想,将对象的创建交给了第三方,完全由程序自己控制:即获得依赖对象的方式反转了

是Spring框架的核心内容

Spring在容器初始化时,先读取配置文件,根据配置文件或元数据创建与组织对象放入容器中,程序使用时再从容器中取出需要的对象*控制反转是一种通过描述(XML或注解)并通过第三方去产生或获取特定对象的方式,在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入

  1. UserDao接口

  2. UserDaoImpl实现类

  3. UserService业务接口

  4. UserServiceImpl业务实现类

需要根据用户修改源代码,会破坏程序的完整性,代价昂贵

通过使用set接口实现:

private UserDao userDao;
    //利用set进行动态实现值的注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

程序不在具有主动性,而是变成被动接受对象

从本质上解决了问题,不用再去管理对象的创建,系统的耦合性大大降低,可以更加专注的在业务的实现上,这就是IOC的原型

3、IOC创建对象的方式 3.1使用无参构造创建,默认 3.2使用有参构造创建
  • 下标赋值

    
        <bean id="user" class="com.zhai.pojo.User">
            <constructor-arg index="0" value="zhaichenji"/>
        bean>
    
  • 通过类型创建

    
        <bean id="user" class="com.zhai.pojo.User">
            <constructor-arg type="java.lang.String" value="zhaichen"/>
        bean>
    
  • 通过参数名来设置

    
        <bean id="user" class="com.zhai.pojo.User">
            <constructor-arg name="name" value="zhai"/>
        bean>
    

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

4、Spring配置 4.1别名

    <alias name="user" alias="userNew"/>
4.2Bean的配置

    <bean id="userT" class="com.zhai.pojo.UserT" name="user2 u2">
        <property name="name" value="zhaichenji"/>
    bean>
  1. import

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

    假设现在项目中有多个人开发,这三个人负责不同的类,不同的类需要注册在不同的bean中,可以利用import将所有人的合并成一个总的。

    • applicationContext.xml

      	<import resource="beans.xml"/>
          <import resource="beans2.xml"/>
          <import resource="beans3.xml"/>
      
5、依赖注入 5.1构造器注入 5.2Set方式注入【重点】
  • 依赖注入:set注入

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

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

【环境搭建】

  1. 复杂类型

    	private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
  2. 真实测试对象

    	private String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        private Map<String,String> card;
        private Set<String> games;
        private String wife;
        private Properties info;
    
  3. beans.xml

    <bean id="student" class="com.zhai.pojo.Student">
    
            <property name="name" value=""/>
    
        bean>
    
  4. 测试类

    public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student =(Student) context.getBean("student");
            System.out.println(student.getAddress());
        }
    
  5. 完善注入信息

    <bean id="address" class="com.zhai.pojo.Address">
            <property name="address" value="宁夏"/>
        bean>
        <bean id="student" class="com.zhai.pojo.Student">
            
            <property name="name" value=""/>
            
            <property name="address" ref="address"/>
            
            <property name="books">
                <array>
                    <value>红楼梦value>
                    <value>数据结构value>
                    <value>大数据value>
                    <value>人工智能value>
                array>
            property>
    
            <property name="hobbys">
                <list>
                    <value>value>
                    <value>value>
                    <value>value>
                list>
            property>
    
            <property name="card">
                <map>
                    <entry key="身份z" value="142536633320125582"/>
                    <entry key="yhk" value="6969665542201236875"/>
                map>
            property>
    
            <property name="games">
                <set>
                    <value>LOLvalue>
                    <value>DNFvalue>
                    <value>CSGOvalue>
                set>
            property>
    
            <property name="wife">
                <null/>
            property>
    
            <property name="info">
                <props>
                    <prop key="学号">12018242282prop>
                    <prop key="性别">prop>
                    <prop key="专业">软件工程prop>
                props>
            property>
        bean>
    
5.3拓展方式注入

可以使用p命名空间和c命名空间进行属性注入

官方解释:


使用:


    <bean id="user" class="com.zhai.pojo.User" p:name="小明" p:age="18"/>
    
    <bean id="user2" class="com.zhai.pojo.User" c:name="小明" c:age="18"/>

测试:

@Test
    public void test2(){
        //p命名空间
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user);
    }
    @Test
    public void test3(){
        //c命名空间
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = context.getBean("user2", User.class);
        System.out.println(user);
    }

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

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

  1. 单例模式(Spring默认机制)

        <bean id="user2" class="com.zhai.pojo.User" c:name="18" c:age="小明" scope="singleton"/>
    
    
  2. 原型模式:每次容器中get的时候,都会产生一个新对象

        <bean id="user2" class="com.zhai.pojo.User" c:name="18" c:age="小明" scope="prototype"/>
    
    
  3. 其余的request、session、application只能在web开发中使用到!

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

三种装配方式:

  1. 在xml中显示的配置
  2. 在java中配置
  3. 隐式的自动装配【重要】
6.1、测试
  1. 环境搭建:一个人有两个宠物
6.2、ByName自动装配

    <bean id="people" class="com.zhai.pojo.People" autowire="byName">
        <property name="name" value="小明"/>
        
        
    bean>
6.3、ByType自动装配

    <bean id="people" class="com.zhai.pojo.People" autowire="byType">
        <property name="name" value="小明"/>
        
        
    bean>

小结:

  • byName时,需保证所有bean的id唯一,且这个bean需要和自动注入的属性set方法一致
  • byType时,需保证所有bean的class唯一,且这个bean需要和自动注入的属性类型一致
6.4、 使用注解实现自动装配

Spring从2.5开始支持注解

“基于注解的配置的引入提出了一个问题,即这种方法是否比 XML“更好”。简短的答案是“取决于情况”。”

使用注解须知:

  1. 导入约束:context约束

  2. 配置注解的支持context:annotation-config/【重要】

    
    <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:annotation-config/>
    
    beans>
    
    

    @Autowired:

    1、直接在属性上使用即可,也可以在set方法上使用**

    2、使用@Autowired可以不写set方法,前提是自动装配属性在IOC中(Spring中)存在,且符合名字byName

    注:

    @Nullable 被次注解标记的字段,值可以为Null
    
    //如果显示required 的属性为false,则该值可以为null
    public @interface Autowired {
        boolean required() default true;
    }
    

    测试代码:

    public class People {
        //如果显示required 的属性为false,则该值可以为null
        @Autowired(required = false)
        private Cat cat;
        @Autowired
        private Dog dog;
        private String name;
    }
    

    如果@Autowired自动装配的环境比较复杂,无法通过一个注解完成时,则可以使用注解【@Qualifier(value = “xxx”)】配置@Autowired的使用,指定一个惟一的bean对象的注入

    public class People {
        @Autowired
        @Qualifier(value = "cat111")
        private Cat cat;
    
        @Autowired
        @Qualifier(value = "dog222")
        private Dog dog;
    }
    

    @Resource注解

    public class People {
        @Resource(name = "cat2")
        private Cat cat;
        @Resource
    
        private Dog dog;
    
        private String name;
    }
    

    小结:

    @Resource和@Autowired的区别:

    • 都是用来自动装配的,都可以放在属性字段上
    • @Autowired通过buType的方式实现,而且必须要求这个对象存在【常用】
    • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现,如果两个都找不到,就会报错,
    • 执行顺序不同:
      • @Autowired通过buType的方式实现,@Resource默认通过byName的方式实现
7、使用注解开发

在Spring4之后,使用注解开发,必须导入AOP的包

使用注解需要导入context约束,增加注解的支持


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
beans>
注解
  • @Autowired:通过名字自动装配
    • 如果@Autowired不能唯一的自动装配,则需要使用@Qualifier(value = “xxx”)
  • @Nullable:被此标记标记的属性,可以为null
  • @Resource:通过名字自动装配,其次是类型
  • @Component:放在类上,说明这个类被Spring管理了,就是bean
  1. bean

  2. 属性如何注入

    @Component
    public class User {
        //通过注解赋值
        //相当于
        @Value("小明")
        public String name;
    }
    
  3. 衍生的注解

    @Component有几个衍生注解,web开发中,按照MVC三层架构:

    • dao【@Repository】
    • service【@Service】
    • controller【@Controller】

    四个注解功能一样,都是将类注册到Spring容器中装配bean

  4. 自动装配置

    - @Autowired:通过名字自动装配
      - 如果@Autowired不能唯一的自动装配,则需要使用@Qualifier(value = "xxx")
    - @Nullable:被此标记标记的属性,可以为null
    - @Resource:通过名字自动装配,其次是类型
    
  5. 作用域

    @Component
    //作用域
    @Scope("prototype")
    public class User {
        //通过注解赋值
        //相当于
        @Value("小明")
        public String name;
    }
    
  6. 小结

    xml与注解

    • xml万能,适用于任何场合,维护简单方便
    • 注解不是自己的类使用不了,维护相对复杂

    最佳实践:

    • xml管理bean
    • 注解完成属性注入
    • 在使用过程中,只需要注意一个问题,必须让注解生效,需要开启注解支持
    
        <context:component-scan base-package="com.zhai"/>
        <context:annotation-config/>
    
8、完全使用Java的方式配置Spring

要完全不使用Spring的xml配置,全权叫个Java来做

JavaConfig是Spring的一个子项目,在Spring4之后,成为了核心功能

实体类

//这个注解的意思就是说明这个类被Spring接管了,注册到了容器中
@Component
public class User {
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    //属性注入值
    @Value("小明")
    public void setName(String name) {
        this.name = name;
    }
}

测试类

@Test
    public void Test1() {
        //如果完全使用配置类方式,就只能通过AnnotationConfigApplicationContext上下文来获取容器,通过配置类的class对象加载
        ApplicationContext context = new AnnotationConfigApplicationContext(ZhaiConfig.class);
        User getUser = context.getBean("user", User.class);
        System.out.println(getUser.getName());
    }

这种纯Java的配置方式,在SpringBoot中,随处可见

9、代理模式

为什么学习代理模式?

  • 因为这是SpringAOP的底层【SpringAOP 和 SpringMVC】

代理模式分类:

  • 静态代理
  • 动态代理
9.1、静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,会做一些附属 *** 作
  • 客户:访问代理对象的人

代码步骤:

  1. 接口

    //租房的接口
    public interface Rent {
        public void rent();
    }
    
  2. 真实角色

    //房东
    public class Host implements Rent{
    
        @Override
        public void rent() {
            System.out.println("房东要出租房子");
        }
    }
    
  3. 代理角色

    public class Proxy implements Rent{
        private Host host;
    
        public Proxy() {
        }
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        public void rent() {
            host.rent();
            seeHouse();
            hetong();
            fare();
        }
    
        //看房
        public void seeHouse(){
            System.out.println("中介带你看房");
        }
        //收中介费用
        public void fare(){
            System.out.println("收中介费");
        }
        //签租赁合同
        public void hetong(){
            System.out.println("签租赁合同");
        }
    }
    
  4. 客户端访问代理角色

    public class Client {
        public static void main(String[] args) {
            //房东要出租房子
            Host host = new Host();
            //代理,中介帮房东出租房子,但是代理角色一般会与一些附属 *** 作
            Proxy proxy = new Proxy(host);
            //你不用面对房东,直接找中介租房子
            proxy.rent();
        }
    }
    

代理模式好处:

  • 可以是真实角色的 *** 作更加纯粹,不用去关注一些公共的业务
  • 公共业务就交给了代理角色去做,实现业务分工
  • 公共业务发生扩展的时候,方便集中管理

代理模式缺点:

  • 一个真实角色就会产生一个代理角色,代码量翻倍,开发效率会变低
9.2、动态代理
  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是直接写出来的
  • 动态代理分为两大类:
    • 基于接口的动态代理
      • JDK动态代理【使用】
    • 基于类的动态代理
      • cglib
    • java字节码实现:javassist

需要两个类:

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

动态代理的好处:

  • 可以是真实角色的 *** 作更加纯粹,不用去关注一些公共的业务
  • 公共业务就交给了代理角色去做,实现业务分工
  • 公共业务发生扩展的时候,方便集中管理
  • 一个动态代理类代理的是一个接口,一般就是对应一类业务
  • 一个动态代理类可以代表多个类,只要实现了同一个接口即可
10、AOP 10.1、AOP介绍

10.2、使用Spring实现AOP

导入AOP依赖包

	<dependencies>
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.4version>
        dependency>
    dependencies>

方式一:使用Spring的API接口【主要是SpringAPI接口实现】


    
    <aop:config>
        
        <aop:pointcut id="pointcut" expression="execution(* com.zhai.service.UserServiceImpl.*(..))"/>
        
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    aop:config>

方式二:自定义来实现AOP【主要是切面】


    <bean id="diy" class="com.zhai.diy.DiyPointCut"/>
    <aop:config>
        
        <aop:aspect ref="diy">
            
            <aop:pointcut id="point" expression="execution(* com.zhai.service.UserServiceImpl.*(..))"/>
            
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        aop:aspect>
    aop:config>

方式三:使用注解实现


    <bean id="annotationPointCut" class="com.zhai.diy.AnnotationPointCut"/>

    <aop:aspectj-autoproxy/>
11、整合Mybatis

步骤:

  1. 导入相关jar包

    • junit
    • myBatis
    • mysql数据库
    • spring相关
    • aop织入
    • mybaits-spring【new】
  2. 编写配置文件

  3. 测试

11.1、回忆Mybatis
  1. 编写实体类
  2. 编写核心配置文件
  3. 编写接口
  4. 编写Mapper.xml
  5. 测试
12、声明式事务 1、回顾事务
  • 要么都成功,要么都失败
  • 事务在项目开发中,十分重要,涉及到数据的一致性问题,不能马虎
  • 确保完整性和一致性

事务的ACID原则:

  • 原子性
  • 一致性
  • 隔离性
    • 多个业务可能 *** 作同一个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写入到存储器中

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/920046.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存