个人笔记Spring5

Spring5

1.简介

1.1简介和包

Spring就是一个轻量级的控制反转(I0C)和面向切面编程(AOP)的框架!

目的:解决企业应用开发的复杂性

功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能

范围:任何Java应用

  • SSH : Sturct2 + Spring + Hibernate

  • SSM: SpringMVC + Spring + Mybatis

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.2.9</version>
</dependency>
​
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>6.2.9</version>
</dependency>

1.2优点

  • Spring 是一个开源的免费的框架(容器)!

  • Spring 是一个轻量级的、非入侵式的框架!

  • 控制反转(IOC),面向切面编程(AOP)!

  • 支持事务的处理,对框架整合的支持!

2.IOC理论推导

1.UserDao 接口

2.UserDaoImpl 实现类

3.UserService 业务接口

4.UserServiceImpl 业务实现类

IOC本质

控制反转loC(inversion of control),是一种设计思想,DI(依赖注入)是实现loC的一种方法,也有人认为D!只是1oC的另一种说法。没有!0C的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

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

3.HelloSpring

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
​
<!--    使用Spring来创建对象,在Spring这些都成为Bean-->
​
    <bean id="hello" class="com.lyj.pojo.Hello">
        <property name="str" value="Spring"></property>
    </bean>
</beans>

有xml就必须要有这个

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

实体类

package com.lyj.pojo;
​
public class Hello {
    private String str;
​
​
    public String getStr() {
        return str;
    }
​
    public void setStr(String str) {
        this.str = str;
    }
​
    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}
​

beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
​
<!--    使用Spring来创建对象,在Spring这些都成为Bean-->
​
<!--    类型 变量名= new 类型();-->
<!--    Hello hello = new Hello();-->
​
<!--    id = 变量名-->
<!--    class = new 的对象-->
<!--    property = 相当于给对象中的属性设置一个值-->
​
    <bean id="hello" class="com.lyj.pojo.Hello">
        <property name="str" value="Spring66666666666666666666666666"></property>
    </bean>
</beans>

测试

import com.lyj.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
public class MyTest {
    public static void main(String[] args) {
        //获取Spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我们的对象现在都在Spring中的管理了,我们要使用,直接去里面取出来就可以
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello.toString());
    }
}
​

4.IOC创建对象的方式

1.使用无参构造创建对象,默认

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

  • 下标赋值

<!--    第一种下标赋值-->
    <bean id="user" class="com.lyj.pojo.User">
        <constructor-arg index="0" value="12113"/>
    </bean>
  • 类型,不建议

<!--    第二种类型赋值,不建议-->
    <bean id="user" class="com.lyj.pojo.User">
        <constructor-arg type="java.lang.String" value="65465644"/>
    </bean>
  • 参数名

<!--    第三种,直接通过参数名来设置-->
    <bean id="user" class="com.lyj.pojo.User">
        <constructor-arg name="name" value="79879798"/>
    </bean>

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

5.Spring配置

5.1别名

<alias name="user" alias="newnewnewUser"/>

5.2Bean的配置

<!--
id : bean 的唯一标识符,也就是相当于我们学的对象名
class : bean 对象所对应的全限定名 : 包名 + 类型
name : 也是别名,而且name可以同时取多个别名,可以用空格,逗号,斜线分割
-->
<bean id="userT" class="com.kuang.pojo.UserT" name="user2 u2,u3/u4">
</bean>

5.3import

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

假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!

张三

李四

王五

applicationContext.xml

<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>

使用的时候,直接使用总的配置就可以了

6. 依赖注入

6.1构造器注入

在上面4.IOC创建对象的方式

6.2Set方式注入(重点)

依赖注入:Set 注入!

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

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

【环境搭建】

  1. 复杂类型

    package com.lyj.pojo;
    ​
    public class Address {
        private String address;
    ​
        public String getAddress() {
            return address;
        }
    ​
        public void setAddress(String address) {
            this.address = address;
        }
    }
    ​
  2. 真实测试对象

    package com.lyj.pojo;
    ​
    import java.util.*;
    ​
    public class Student {
        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;
    ​
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public Address getAddress() {
            return address;
        }
    ​
        public void setAddress(Address address) {
            this.address = address;
        }
    ​
        public String[] getBooks() {
            return books;
        }
    ​
        public void setBooks(String[] books) {
            this.books = books;
        }
    ​
        public List<String> getHobbys() {
            return hobbys;
        }
    ​
        public void setHobbys(List<String> hobbys) {
            this.hobbys = hobbys;
        }
    ​
        public Map<String, String> getCard() {
            return card;
        }
    ​
        public void setCard(Map<String, String> card) {
            this.card = card;
        }
    ​
        public Set<String> getGames() {
            return games;
        }
    ​
        public void setGames(Set<String> games) {
            this.games = games;
        }
    ​
        public String getWife() {
            return wife;
        }
    ​
        public void setWife(String wife) {
            this.wife = wife;
        }
    ​
        public Properties getInfo() {
            return info;
        }
    ​
        public void setInfo(Properties info) {
            this.info = info;
        }
    ​
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", address=" + address +
                    ", books=" + Arrays.toString(books) +
                    ", hobbys=" + hobbys +
                    ", card=" + card +
                    ", games=" + games +
                    ", wife='" + wife + '\'' +
                    ", info=" + info +
                    '}';
        }
    }
    ​

  3. Beans.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
                           https://www.springframework.org/schema/beans/spring-beans.xsd">
​
​
    <bean name="student" class="com.lyj.pojo.Student">
<!--        第一种普通值注入,直接使用values-->
        <property name="name" value="张三"/>
    </bean>
</beans>

  1. 测试

import com.lyj.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.getName());
​
    }
}
​

6.2.1完善注入信息

<?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
                           https://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean name="address" class="com.lyj.pojo.Address">
        <property name="address" value="地球"></property>
    </bean>
​
​
    <bean name="student" class="com.lyj.pojo.Student">
<!--        第一种 普通值注入,使用values-->
        <property name="name" value="张三"/>
<!--        第二种 Bean注入,使用ref-->
        <property name="address" ref="address"/>
<!--        第三种 数组注入-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
            </array>
        </property>
<!--        List注入-->
        <property name="hobbys">
            <list>
                <value>爱好1</value>
                <value>爱好2</value>
            </list>
        </property>
<!--        Map注入-->
        <property name="card">
            <map>
                <entry key="身份证" value="123123"/>
                <entry key="银行卡" value="654654"/>
            </map>
        </property>
<!--        Set注入-->
        <property name="games">
            <set>
                <value>游戏1</value>
                <value>游戏2</value>
            </set>
        </property>
<!--        NULL注入-->
        <property name="wife">
            <null/>
        </property>
<!--        properties注入-->
        <property name="info">
            <props>
                <prop key="学号">123123132</prop>
                <prop key="性别">男</prop>
                <prop key="姓名">张三</prop>
            </props>
        </property>
​
​
    </bean>
</beans>

6.3拓展方式注入

6.3.1 p命名空间注入

对应Set

<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">
​
<!--    p命名空间注入,可以直接注入属性的值:property-->
    <bean id="user" class="com.lyj.pojo.User" p:name="张三" p:age="20"/>
<!--    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"-->
<!--          destroy-method="close"-->
<!--          p:driverClassName="com.mysql.jdbc.Driver"-->
<!--          p:url="jdbc:mysql://localhost:3306/mydb"-->
<!--          p:username="root"-->
<!--          p:password="misterkaoli"/>-->
​
</beans>

import com.lyj.pojo.Student;
import com.lyj.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
​
    }
​
    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = (User)context.getBean("user");
        //User user1 = context.getBean("user", User.class);
        System.out.println(user);
​
    }
​
}

6.3.2 c命名空间注入

对应构造器

<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
    https://www.springframework.org/schema/beans/spring-beans.xsd">
​
<!--    p命名空间注入,可以直接注入属性的值:property-->
    <bean id="user1" class="com.lyj.pojo.User" p:name="张三" p:age="20"/>
<!--    p命名空间注入,通过构造器注入:construct-args-->
    <bean id="user2" class="com.lyj.pojo.User" c:name="李四" c:age="30"/>
<!--    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"-->
<!--          destroy-method="close"-->
<!--          p:driverClassName="com.mysql.jdbc.Driver"-->
<!--          p:url="jdbc:mysql://localhost:3306/mydb"-->
<!--          p:username="root"-->
<!--          p:password="misterkaoli"/>-->
​
</beans>

import com.lyj.pojo.Student;
import com.lyj.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
​
public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());
​
    }
​
    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user = (User)context.getBean("user2");
        //User user1 = 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"

6.4Bean的作用域

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

<bean id="user1" class="com.lyj.pojo.User" p:name="张三" p:age="20" scope="singleton"/>

2.原型模式:每次从容器中get的时候,都会产生一个新对象

<bean id="user1" class="com.lyj.pojo.User" p:name="张三" p:age="20" scope="prototype"/>

3.其余的request,session,application,这些只能在web开发中使用到

7. Bean的自动装配

自动装配核心概念

  • 自动装配是 Spring 满足 bean 依赖的一种方式

  • Spring 会在上下文中自动寻找,并自动给 bean 装配属性

Spring 装配的三种方式

  1. 在 xml 中显式配置

  2. 在 java 中显式配置

  3. 隐式的自动装配 bean

7.1测试

环境搭建:People,Dog,Cat

7.2 ByName自动装配

<?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 
                           https://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean id="cat" class="com.kuang.pojo.Cat"/>
    <bean id="dog" class="com.kuang.pojo.Dog"/>
​
    <!-- 
        byName:会自动在容器上下文中查找,和自己对象 set 方法后面的值对应的 beanid!
    -->
    <bean id="people" class="com.kuang.pojo.People" autowire="byName">
        <property name="name" value="张三"/>
    </bean>
​
</beans>

7.3ByType自动装配

<?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 
                           https://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <bean class="com.kuang.pojo.Cat"/>
    <bean class="com.kuang.pojo.Dog"/>
​
    <!-- 
        byType:会自动在容器上下文中查找,和自己对象 属性类型相同的 beanid!
    -->
    <bean id="people" class="com.kuang.pojo.People" autowire="byType">
        <property name="name" value="张三"/>
    </bean>
​
</beans>

小结:

  • pyname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!

  • bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!

7.4 使用注解实现自动装配

使用注解:

1.导入约束

2.配置注解的支持:context:annotation-config/

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
​
    <context:annotation-config/>
​
</beans>

@Autowired

直接在属性是使用即可,也可以咋iset方式上使用

使用Autowired外面可以不用编写Set方法,前提是自动装配的属性在IOC(Spring)容器中存在,且符合名字ByName

另外:

@Nullable 字段标记了这个注解,说明这个字段可以为null
​
import org.springframework.lang.Nullable;导包
​
    public People(@Nullable String name) {
        this.name = name;
    }

//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required= false)
private Cat cat;

@Quelifier

指定一个

@Quelifier(value= "dog222")
private Dog dog;

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value="xxx")去配置@Autowired的使用,指定一个唯一的bean对象注入!

@Resource注解

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

小结:@Resource 和 @Autowired 的区别

  • 相同点: 均用于自动装配,可直接标注在属性字段上实现依赖注入。

  • 不同点:

    1. @Autowired

      • 默认通过 byType(按类型) 方式匹配 Bean(若存在多个同类型 Bean,需结合 @Qualifier 按名称精准注入 );

      • 要求依赖的对象必须存在(默认 required = true ),否则启动报错(常用场景下需确保依赖可用)。

    2. @Resource

      • 默认通过 byName(按名称) 方式匹配 Bean(根据属性名 / 字段名查找容器中对应 id 的 Bean );

      • 若按名称找不到匹配 Bean,会 fallback 到 byType(按类型) 查找;

      • 若名称、类型均无匹配,才会报错(适配性更强,支持更灵活的注入逻辑 )。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值