Spring入门

1. 简介

2002年首次退出Spring的雏形,interface21 框架
2004年4月24日以interface21 为基础发布Spring1.0 正式版
Rod Johnson Spring Framwork创始人,音乐学
Spring理念:使现有技术更加容易使用,本身是一个大杂烩整合了现有的技术框架

SSH:Struct2 + Spring + Hibernate(全自动)
SSM:SpringMVC + Spring + Mybatis(半自动更灵活)

优点

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

总结:Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架

组成

七大模块

image-20211018151244911

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

学习Spring Boot 的前提就是完全掌握Spring SpringMVC Spring起到承上启下的作用

弊端:整合的框架太多之后,配置会非常繁琐,人称 ” 配置地狱 “

2、IOC

IOC是一种思想,DI(依赖注入)是实现IOC的一种方法

控制反转:

​ 以前的我们要实现一个业务逻辑需要使用Dao层具体实现,Service层调用Dao层逻辑代码

​ 并且还要通过每一个实现类都要定义一个接口再做出它的具体实现,如果有多个Dao业务,就需要在ServiceImpl 中改变它的具体实现,但是代码一旦多了起来这种方式就不可行了

​ IOC就是将将原来的由程序员控制实现的方式转变一下,添加一个set方法由用户动态的注入所需的参数,程序就不需要管创建了。

之前所写的代码所有东西都是由程序去进行创建,而现在是有我们自行控制创建对象主动权交给了调用者,程序不用去管怎么去创建了,只负责提供一个接口

image-20211018222105781

IOC是一种通过描述(XML 或 注解)并通过第三方生产或获取特定对象的方式,在Spring中实现IOC 的是IOC容器,其实现方法是DI

image-20211019090412129

3、第一个Spring程序

  1. 导入pom依赖

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.11</version>
    </dependency>
    
  2. 创建 hellospring类

    package 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 "pojo.hello{" +
                    "str='" + str + '\'' +
                    '}';
        }
    }
    
  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 id="hello" class="pojo.Hello">
            <!--
                value:引用具体的值,基本类型
                ref  :引用spring容器中创建好了的对象
            -->
            <property name="str" value="hello spring"/>
    
            <!-- collaborators and configuration for this bean go here -->
        </bean>
    
    </beans>
    
  4. 测试

    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import pojo.Hello;
    
    public class MyTest {
        @Test
        public void appTest(){
            // 获取ApplicationContext,拿到spring 容器
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
            // 获取过后,需要什么就直接get什么
            Hello hello = (Hello)applicationContext.getBean("hello");
            System.out.println(hello.getStr());
        }
    }
    

到这里,要实现不同的操作都可以直接到 beans.Xml 配置文件中去修改,IOC就是一句话:对象由Spring来创建、管理、装配

4、IOC创建对象的方式

默认使用无参构造

可以构造有参构造

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

并且对象是唯一的

  1. 下标赋值(Constructor argument index
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>
  1. 类型匹配(Constructor argument type matching
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
  1. name(Constructor argument name
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

5、Spring 的配置

1.别名

<!-- 添加别迷宫之后就也可以通过别名来获取这个对象 --><alias name = "user" alias="userNew"/>

2.Bean的配置

id : 变量名

class: 全限定类名

name: 也是一个种起别名的方式,不过它可以起多个,支持多种分隔符

property: 用来注入这个类的属性

​ name: 属性名

​ value: 属性值

​ ref : 将属性值设置为Spring容器中已经创建好了的对象

<bean id="userT" class="com.kuang.pojo.userT" name="user2 u2,uT">	<property name="name" value="spring"></bean>

3.import

一般用于团队开发的时候,将多个配置文件合并为一个

将多个人开发的的beans.xml 合并为一个 applicationcontext.xml

<import resource="beans1.xml"/><import resource="beans2.xml"/>...

6、依赖注入

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

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

1.构造器注入

  • 参照于第4点

2.Set方式注入【重点】

bean 中使用 property 标签进行注入

不同的类型有不同的注入方式

<!-- 普通值注入 --><property name="name" value="value"/><!-- bean注入 --><property name="beanName" ref="classname"/><!-- 数组注入 --><property name="arrayName">	<array>        <value>value1</value>        <value>value2</value>        ...    </array></property><!-- list注入 --><property name="listName">	<list>        <value>value1</value>        <value>value2</value>        ...    </list></property><!-- map注入 --><property name="mapName">	<map>		<entry key="keyName" value="value">		<entry key="keyName" value="value">        ...    </map></property>        <!-- set注入 --><property name="setName">	<set>        <value>value1</value>        <value>value2</value>    </set></property>        <!-- null --><property name="listName">    <null/></property>        <!-- properties --><property name="listName">    <props>        <prop key="keyName">value</prop>        <prop key="keyName">value</prop>    </props></property>

3.拓展方式注入

官网提供了 p-namespacec-namespace 两种扩展方式

分别对应了 property (set注入) 和 constructor(构造器注入)方式,更简单快捷

但需要提前导入xml 约束

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

c-namespace 方式:

<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    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">    <bean id="beanTwo" class="x.y.ThingTwo"/>    <bean id="beanThree" class="x.y.ThingThree"/><!-- traditional declaration with optional argument names -->    <bean id="beanOne" class="x.y.ThingOne">        <constructor-arg name="thingTwo" ref="beanTwo"/>        <constructor-arg name="thingThree" ref="beanThree"/>        <constructor-arg name="email" value="something@somewhere.com"/>    </bean><!-- c-namespace declaration with argument names -->    <bean id="beanOne" class="x.y.ThingOne"              c:thingTwo-ref="beanTwo"             c:thingThree-ref="beanThree"              c:email="something@somewhere.com"/></beans>

p-namespace 方式:

<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">    <bean name="jane" class="com.example.Person">        <property name="name" value="Jane Doe"/>    </bean>        <bean name="john-classic" class="com.example.Person">        <property name="name" value="John Doe"/>        <property name="spouse" ref="jane"/>    </bean>    <bean name="john-modern"class="com.example.Person"          p:name="John Doe"          p:spouse-ref="jane"/>    </beans>

4.bean的作用域(Scope)

ScopeDescription
singleton(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocketScopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.
  1. 单例模式(Spring默认机制)
<bean id="accountService"class="com.something.DefaultAccountService" scope="singleton"/>

每次创建都是一个相同的对象

  1. 原型模式:每次从容器中get 的时候都会产生一个新的对象
<bean id="accountService"class="com.something.DefaultAccountService" scope="prototype"/>
  1. 其余的request、session、application这些只能在web开发中使用到

7、bean的自动装配(autowire)

是Spring满足bean依赖的一种方式

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

Spring中的三种装配方式:

  1. xml中显式配置
  2. Java中显式配置
  3. 隐式的自动装配bean【重要】

传统的注入方式

<bean id="cat" class="Cat"/><bean id="dog" class="Dog"/><bean id="person" class="Person">    <property name="name" value="zj"/>    <property name="cat" ref="cat"/>    <property name="dog" ref="dog"/></bean>

ByName autowire

自动在容器上下文中查找和自己对象set方法后面的值对应的 bean id。

需要保证所有bean 的 id 唯一,并且bean 需要和自动注入的属性的set方法的xxx值一致

<bean id="cat" class="Cat"/>
<bean id="dog" class="Dog"/>

<bean id="person" class="Person" autowire="byName"/>

ByType autowire

自动在容器上下文中查找和自己对象属性类型想通过的bean。

需要保证所有bean 的 class 唯一,并且需要和自动注入的属性的类型一致

<bean id="cat" class="Cat"/>
<bean id="dog" class="Dog"/>

<bean id="person" class="Person" autowire="byType"/>

使用注解实现自动装配

jdk1.5 支持的注解,Spring 2.5就支持注解了

The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML. The short answer is “it depends.”

  1. 导入约束:context约束
xmlns:context="http://www.springframework.org/schema/context"
  1. 配置注解支持: < context:annotation-config/>
<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"
    <!-- 1.1.导入约束 -->
    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
        <!-- 1.2.导入约束 -->            
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- 2.配置注解支持 -->
    <context:annotation-config/>

</beans>

@Autowired

可以直接写在 属性 或者 set方法 上。

使用Autowired 就可以不用编写set方法了,前提是这个自动装配的属性在IOC(Spring)容器中存在,且符合命名 byName

@Autowired
private Dog dog;

@Autowired
public void setCat(Cat cat){
    this.cat = cat;
}

如果使用 @Nullable 标注了一个字段

或 标注时使用 @Autowired (requierd = false)

则说明这个字段可以为 null

// 显式定义它的required 属性为false 默认为true  ,说明这个对象可以为空
@Autowired(required = false)  
private Cat cat;

@Nullable

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

@Qualifier

如果 @Autowire 自动配置的环境比较复杂,无法实现自动装配,可以使用

@Qualifier(value = “xxx”) 去指定一个唯一的 bean

@Autowired
@Aualifier(value = "dog")
private Dog dog;

@Resouce

Java 的原生注解

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

Autowired 和 Resource 的区别

  • 都是用来实现自动装配的
  • Autowired 通过 byType 的方式来实现,且要求这个对象必须存在【重点】
  • Resource 通过 byName 的方式实现,如果找不到名字,就通过 byType 方式来实现,否则报错【重点】,它类似于 Qualifier + Autowired 的结合

8、Spring注解开发

在Spring 4 之后,要使用注解开发,必须要保证 aop 的包导入了

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

指定要扫描的包,这个包下面的注解就会生效

<?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:component-scan base-package="pojo"/>
    <!--  增加注解的支持,与spring  -->
    <context:annotation-config/>

</beans>
  1. bean
@Component	// 组件,放在类上,说明这个类被Spring 管理了,就是bean
public class User{
 	private String name = "小明";   
}
  1. 属性注入
@Component
public class User{
	@Value("小明")  // 相当于 <property name="name" value="小明"/>
  	private String name;  
}
  1. 衍生的注解

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

  • dao : @Repositotry
  • service : @service
  • controller:@Controller
@Repository
public class User{
	@Value("小明")  // 相当于 <property name="name" value="小明"/>
  	private String name;  
}
  1. 自动装配
@Autowired	// 类型、名字
@Resource   // 名字、类型
  1. 作用域
@Repository
@Scope("prototype")
public class User{
	@Value("小明")  // 相当于 <property name="name" value="小明"/>
  	private String name;  
}
  1. 小结
  • xml与注解

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

    • xml用来管理bean
    • 注解负责完成属性的注入
    • 使用过程中,让注解生效就需要开启注解的支持
    <!--  指定要扫描的包,这个包下的注解就会生效  -->
    <context:component-scan base-package="pojo"/>
    <!--  增加注解的支持,与spring  -->
    <context:annotation-config/>
    

9、JavaConfig实现配置

实体类

@Component      // 这里的 @component 说明这个类被Spring接管了,注册到了容器中
public class User {

    @Value("zj")    // 属性注入值
    private String name;

    public String getName() {
        return name;
    }

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

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

配置类

@Configuration // 因为它本身也是一个Component,它也会被Spring 托管,注册到容器中,他就变成了一个配置类同 beans.xml
@Import(Javaconfig2.class)
//@Scope("singlet")
@ComponentScan("pojo")
public class JavaConfig {

    @Bean       // 注册一个bean,相当于一个bean标签,方法名相当于 id ,返回值相当于class
    public User getUser(){
        return new User();  // 要注入到 bean中的对象
    }
}

测试类

public void test(){
    // AnnotationConfigApplicationContext 通过配置类来获取Spring 容器
    ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
    // 方法名就相当于一个bean
    User getUser = (User)context.getBean("getUser");
    System.out.println(getUser);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值