初识Spring

Spring是一个轻量级的Java框架,通过使用Spring框架,我们可以更加容易地实现企业级应用程序开发,从而使代码更加易于维护和管理。其中,IoC(Inversion of Control)和DI(Dependency Injection)是Spring框架中最为重要的两个特性。

IoC是一种设计模式,其核心思想是将对象的创建、销毁以及管理等工作从应用程序中分离出来,由IoC容器负责完成。Spring通过IoC容器实现了对象之间的解耦和灵活性,降低了代码的耦合度,使得代码更易于维护和修改。

DI是IoC的一种实现方式,通过DI,我们可以将应用程序中的依赖关系从代码中分离出来,由IoC容器负责将依赖关系注入到对象中。通过DI,我们可以实现应用程序中各个对象之间的解耦,使得代码更加灵活、可扩展和可测试。

在Spring框架中,Bean是一个重要的概念,其表示一个由IoC容器管理的对象。在Spring框架中,我们可以通过配置文件或者注解的方式定义Bean,通过IoC容器获取Bean实例对象。

下面,我们来看一个简单的示例:

首先,我们需要定义一个UserDao接口和其实现类UserDaoImpl,代码如下:

package com.congyun.dao;

public interface UserDao {
}

package com.congyun.dao.impl;

public class UserDaoImpl implements UserDao {

}

然后,我们定义一个UserService接口和其实现类UserServiceImpl,其中,UserServiceImpl中定义了一个成员变量UserDao,并提供了setUserDao方法,用于接收注入的对象,代码如下:

package com.congyun.service;

import com.congyun.dao.UserDao;

public interface UserService {
}

package com.congyun.service.impl;

import com.congyun.dao.UserDao;
import com.congyun.service.UserService;

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }

}

接着,我们需要在Spring的配置文件beans.xml中配置UserDao和UserServiceImpl,其中,通过元素来实现对UserDao的注入,代码如下:

<?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.xsd">
    <!--配置UserServiceImpl-->
    <bean id="userService" class="com.congyun.service.impl.UserServiceImpl">
        <!--依赖注入-->
        <property name="userDao" ref="userDao"/>
    </bean>
    <!--配置UserDao-->
    <bean id="userDao" class="com.congyun.dao.impl.UserDaoImpl">

    </bean>
</beans>

这部分是在Spring的XML配置文件中进行依赖注入的配置。其中,property标签表示设置对象属性的元素,name属性表示被设置的属性名称,ref属性表示引用另一个bean的ID,这个被引用的bean将会被注入到当前对象的对应属性中。

在上面的例子中,UserServiceImpl类中的userDao属性被设置为userDao这个bean,即将会把userDao这个bean注入到UserServiceImpl类中的userDao属性中。这样,UserServiceImpl类中就可以使用userDao这个对象,而这个对象是通过依赖注入方式被注入的。

最后,我们编写一个测试类BeanTest,在该测试类中实现了通过Spring IoC容器获取UserService实例的功能,同时也演示了如何通过依赖注入方式将UserDao实例注入到UserService中。

在BeanTest中,我们首先创建了一个DefaultListableBeanFactory实例beanFactory,这个实例就是Spring IoC容器的实现之一。然后我们创建了一个XmlBeanDefinitionReader实例reader,这个实例用于从配置文件beans.xml中读取bean的定义信息,并将这些信息加载到beanFactory中。最后,我们通过调用beanFactory的getBean方法获取了一个UserService实例。

package com.congun.test;

import com.congyun.service.UserService;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;

public class BeanTest {

    @Test
    public void testBean() {
        // 创建工厂对象
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 创建一个读取器
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        // 读取配置文件给工厂
        reader.loadBeanDefinitions("beans.xml");
        // 根据id获取Bean实例对象
        UserService userService = (UserService) beanFactory.getBean("userService");
        System.out.println(userService);
    }
}

在beans.xml配置文件中,我们定义了两个bean,一个是UserService的实现类UserServiceImpl,另一个是UserDao的实现类UserDaoImpl。通过在UserService实现类中定义了一个setUserDao(UserDao userDao)方法,并在beans.xml文件中配置了UserService实现类中userDao属性的注入,就实现了将UserDao实例注入到UserService实例中的功能。

总的来说,Spring IoC容器实现了对象的生命周期管理、依赖注入等功能,可以大大简化Java应用程序的开发过程。通过在配置文件中定义bean,开发人员可以专注于业务逻辑的实现,而不需要考虑对象的创建、销毁和依赖关系的管理等细节。

需要注意的是,测试类需要引入相应的依赖,比如JUnit和Spring Framework相关的依赖,才能正常运行。

在 Spring 容器中,对于某个特定的 bean,在同一次请求中,无论使用多少次 getBean() 方法获取该 bean 实例,都只会返回同一个实例。这是因为 Spring 容器默认使用单例模式来管理 bean。因此,无论获取多少次 “userService” 这个 bean,都会得到同一个 UserService 实例,其 hashCode 值相同。

可以通过设置 bean 的作用域(scope)来实现不同的实例化行为。默认情况下,Spring 容器会为每个 bean 创建一个单例(singleton)的实例,并且在整个应用程序的生命周期中,都只会存在一个该 bean 的实例。这就是为什么你的代码多次获取同一个 bean 实例时,输出的结果都是相同的。

如果想让每次获取该 bean 时都返回一个新的实例,可以将 bean 的作用域设置为 prototype,这样 Spring 容器在每次获取该 bean 时都会创建一个新的实例。在 XML 配置文件中,可以通过如下方式设置 bean 的作用域:

<bean id="userService" class="com.congyun.service.impl.UserServiceImpl" scope="prototype">
    <property name="userDao" ref="userDao"/>
</bean>

在 Java 中,以 Abstract 开头的类通常是为了提供一些抽象的基础实现,以供其他具体实现进行继承或实现。这些类一般都包含一些抽象方法和具体方法,具体方法提供了一些共同的行为,而抽象方法则需要具体子类实现以提供更具体的行为。

在 Spring 中,AbstractRefreshableApplicationContext 提供了一个基础的抽象实现,封装了 ApplicationContext 的基本生命周期以及容器的初始化和刷新过程等。通过继承 AbstractRefreshableApplicationContext 类,可以更加方便地创建自定义的 ApplicationContext 实现。

抽象类不能被实例化,即不能用来创建对象。抽象类是用来被子类继承并实现其抽象方法或覆盖其非抽象方法的。在Java中,如果一个类中包含了抽象方法,那么该类必须声明为抽象类。抽象类是一种特殊的类,它不能被实例化,只能被子类继承。在实际的应用中,我们通常定义一个抽象类来封装一些通用的方法或属性,然后让子类去继承这个抽象类,并实现其抽象方法,这样就可以达到代码复用的目的。

FileSystemXmlApplicationContext和ClassPathXmlApplicationContext都是Spring IoC容器的实现,用于加载和管理bean实例。它们的区别在于:

  1. 文件路径不同:FileSystemXmlApplicationContext从文件系统中加载配置文件,而ClassPathXmlApplicationContext从类路径中加载配置文件。

  2. 配置文件的加载方式不同:FileSystemXmlApplicationContext需要指定配置文件的绝对路径,而ClassPathXmlApplicationContext则可以直接指定配置文件的名称(如果在classpath根目录下)或相对路径。

因此,如果应用程序需要加载位于文件系统中的配置文件,可以使用FileSystemXmlApplicationContext;如果应用程序需要加载位于classpath中的配置文件,可以使用ClassPathXmlApplicationContext。

BeanFactory与ApplicationContext的关系

  1. BeanFactory是Spring的早期接口,称为Spring的Bean工厂,ApplicationContext是后期更高级接口,称之为Spring容器;
  2. ApplicationContext在BeanFactory基础上对功能进行了扩展,例如:监听功能、国际化功能等。BeanFactory的API更偏向底层,ApplicationContext的API大多数是对这些底层API的封装;
  3. Bean创建的主要逻辑和功能都被封装在BeanFactory中,ApplicationContext不仅继承了BeanFactory,而且ApplicationContext内部还维护着BeanFactory的引用,所以,ApplicationContext与BeanFactory既有继承关系,又有融合关系。
  4. Bean的初始化时机不同,原始BeanFactory是在首次调用getBean时才进行Bean的创建,而ApplicationContext则是配置文件加载,容器一创建就将Bean都实例化并初始化好。当没有添加scope="prototype"属性时添加了scope="prototype"属性后,需要使用Bean实例时才对实例进行初始化操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值