Spring框架

Spring框架简介

Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

IOC简介

spring中提供了IOC容器,即IOC(Inversion Of Control)控制反转,所谓控制反转就是说将对象的创建交给外部容器完成,这个就是控制反转。
spring中使用控制反转来实现对象在不同程序中的使用。而容器存在的必要性就是管理对象。

我们以一个购买图书的场景来分析使用Java实例,使用相关对象是需要new创建并持有,它会存在以下缺点。
1、实例化一个组件会比较困难,两个对象都需要创建数据源,读取配置,谁来创建和处理等都是一个问题。
2、很多组件需要销毁来释放资源,采用共享的方式,不好确保正确销毁。
3、随着映入到的业务组件越来越多,对组件的共享管理也就越来越复杂。

Spring可以提供IOC容器,来管理所有的组件(对象),所有的对象的创建、销毁都交给容器,谁需要使用对象,在容器中获取该对象的使用权,哪一个对象需要,就将使用的对象注入到该对象,对于使用方而言,只需要关注使用即可,而对象的生命周期的管理就交给IOC容器 进行管理。

IOC容器负责实例化所有的组件,需要进行 依赖的对象都交给容器管理,IOC最简单的方式就是通过xml方式

<beans> 
  数据源交给容器管理
  <bean id="datasource" class="DataSourceService" >
  
    <bean id="userservice" class="UserService"> 
       <property name="datasource" ref="datasource"/>
    </bean> 
    
    ...
</beans>

在其他类中要获取用户信息,通过容器:context提供的方式来获取用户实例context.getName(“userservice”),就会在容器中找id=“userservice”,进而获取该对象的实例。

IOC的思想

对象的创建交给外部容器完成,这个就是控制反转
spring中使用控制反转来实现对象在不同程序中的使用
控制反转解决对象处理的问题,将对象交给容器进行创建

依赖注入(DI):dendendency injection
对象与对象之间的依赖问题即依赖注入 AOP->DI
Spring使用依赖注入来实现对象之间的依赖关系
在对象创建之后,对象的关系处理就是依赖注入

无论对象的创建,处理对象之间的依赖关系,对象创建的时间还有对象创建的数量,都可以在spring的IOC容器上配置对象的信息就好了

Spring管理对象

spring集成依赖

        <!--spring的核心依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>

        <!--log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

spring的配置文件(Applicationcontext.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
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
 
</beans>   

创建实体类

先创建需要交给容器管理的类

public class User {
    private Integer id;
    private String name;

   
}

随后将user对象交给容器管理

    <!--使用bean标签类管理对象 id:属性标识对象,不可重复  class属性代表要管理的对象的全路径-->
    <bean id="user" class="com.tulun.bean.User"/>

通过容器来获取User对象

        //获取IOC容器,通过读取classpath路径下的spring的配置文件
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationcontext.xml");
        //在IOC容器获取需要的对象实例
        User user = (User) applicationContext.getBean("user");

IOC容器在这里插入图片描述

在这里插入图片描述
Spring IOC容器的继承关系,ApplicationContext是BeanFactory子接口实现之一,BeanFactory是IOC容器定义的最底层的接口。

ApplicationContext是高级实现之一,对BeanFactory的接口做了很多的扩展,大部分情况使用ApplicationContext。

ApplicationContext接口常见的实现类
ClassPathXmlApplicationContext

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationcontext.xml");

用于读取classpath中的资源

FileSystemXmlApplicationContext

FileSystemXmlApplicationContext applicationContext1 = new FileSystemXmlApplicationContext("d://test.xml");

读取系统指定的资源文件

XmlWebApplicationContext

 XmlWebApplicationContext applicationcontext = new XmlWebApplicationContext();

读取web环境下的资源文件

我们可以通过一幅图来了解一下IOC容器获取bean对象的过程
在这里插入图片描述

Spring对Bean的实例化方式

基于配置形式

通过无参构造函数实例化

<!--通过无参构造来实例化Bean-->
    <bean id="user" class="com.tulun.bean.User" scope="singleton"/>

spring容器对上面的类的实例化采用的是无参构造函数来实例化bean
注意:如果不指定无参构造函数,会生成一个默认的无参构造函数,如果指定了有参构造函数,(就不会生成默认的无参构造函数),就必须显性的写明一个无参构造函数

通过静态工厂方式实例化

首先创建静态工厂类来获取User对象

public class StaticFactory {
    public static User getUser(){
        return new User();
    }
}

spring容器管理配置如下:

<!--通过静态工厂类获取User对象-->
    <bean id="user1" class="com.tulun.factory.StaticFactory" factory-method="getUser"/>

静态工厂方式获取对象是 class属性工厂类的全路径,factory-method属性指在工厂类中指定的方法来获取需要的对象

通过普通工厂方式来实例化Bean

创建一个普通工厂来管理user

/**
 * 普通工厂
 */
public class CommonFactory {

    public User getUser(){
        return new User();
    }
}

spring 容器的配置如下:

<!--通过普通工厂类获取User对象-->
    <!--先获取工厂实例-->
    <bean id="factory" class="com.tulun.factory.CommonFactory"/>
    <!--指定工厂类的方法-->
    <bean id="user2"  factory-bean="factory" factory-method="getUser"/>

首先需要获取工厂实例,通过普通工厂实例获取user对象时,factory-bean属性指的是容器管理的工厂对象,factory-method属性指的是工厂中获取user对象的方法。

基于注解形式

基于注解形式比xml方式更加简单,开发更快,在前面介绍mybatis时我们也使用过注解

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

    <!--开启扫描注解:指定的包路径下的类,会扫描的到类的方法,属性上-->
    <context:component-scan base-package="com.tulun.bean"/>
    
    <!--只扫描类中属性的注解(不建议使用)-->
    <!--<context:annotation-config></context:annotation-config>-->
    
</beans>    

在对应的类上面去添加相应的注解

@Component("user")
//注解中user=XML配置形式中bean  id属性
public class User {
    private Integer id;
    private String name;
}

这里的注解使用@Compoment,其他注解如下

  • @Component:通用注解
  • @Repository:对DAO层实现类进行标注
  • @Service:对Service层业务逻辑层进行标注
  • @Controller:对Controller的实现类进行标注
    其实这四个注解可以通用,功能是一样的,可以互换,我们使用不同注解主要是加入我们要进行web开发时,可以区别不同的业务层,使逻辑更加清晰。

Spring中依赖注入方式

bean的实例化说明的是IOC的问题,创建对象之后对象中的属性如何赋值问题,即依赖注入问题(DI)。这里同样有两种方式,一是通过xml配置方式进行依赖注入,另一种便是注解形式进行依赖注入。

基于xml配置实现依赖注入

通过有参构造函数

这种方式,实体类必须提供有参构造函数。

public class User {
    private Integer id;
    private String name;

    /**
     * 有参构造函数
     */
    public User(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

容器中要进行以下配置

public class User {
    private Integer id;
    private String name;

    /**
     * 有参构造函数
     */
    public User(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

通过有参构造函数完成依赖注入时,使用constructor-arg标签进行属性赋值。

setter方式

这需要类中具有setter方法

public class User {
    private Integer id;
    private String name;

    public User() {
    }
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

而容器中的配置信息如下:

    <!--依赖注入:setter方式-->
    <bean id="user4" class="com.tulun.bean.User">
        <!--属性注入-->
        <property name="id" value="2"/>
        <property name="name" value="基础班"/>
    </bean>

setter方式的依赖注入:使用property标签进行赋值

也可以对自定义类型进行注入,无论是set还是有参构造都可以。在对它进行赋值时要使用ref

    <bean id="user3" class="com.tulun.bean.User">
        <constructor-arg name="book" ref="book"/>
    </bean>

如果要注入集合类型:数组、set、list、Map等等
在这里插入图片描述
以map类型为例

public class User {
    private Integer id;
    private String name;
    private Map<String ,String> map; //map 类型属性

在容器中的配置

 <!--map集合类型-->
    <bean id="user5" class="com.tulun.bean.User">
        <!--属性注入-->
        <property name="id" value="3"/>
        <property name="name" value="基础班1"/>
        <property name="map" >
            <
            <map >
                <entry key="1" value="11"></entry>
                <entry key="2" value="22"></entry>
                <entry key="3" value="33"></entry>
            </map>
        </property>
    </bean>

基于注解形式注入依赖

@Value(“3”)//注入普通类型属性
@Resource //注入对象类型
@Autowired //注入对象类型,默认是按照类型注解

依赖的注入都是在类的属性上

那@Resource 和@Autowired有什么区别呢?

Spring中,@Resource和@Autowired都是做bean的注入时使用。使用过程中,有时候@Resource 和 @Autowired可以替换使用;有时,则不可以。

共同点
@Resource和@Autowired都可以作为注入属性的修饰,在接口仅有单一实现类时,两个注解的修饰效果相同,可以互相替换,不影响使用。

不同点
@Resource是Java自己的注解,@Resource有两个属性是比较重要的,分是name和type;Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

@Autowired是spring的注解,是spring2.5版本引入的,Autowired只根据type进行注入,不会去匹配name。如果涉及到type无法辨别注入对象时,那需要依赖@Qualifier或@Primary注解一起来修饰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

降温vae+

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值