Spring 讲解(二 )

1、Spring 容器加载的3种方式

public class ServiceTest {
        public static void main(String[] args) {
            //Spring容器加载有3种方式

            //第一种:ClassPathXmlApplicationContext ClassPath类路径加载,指的就是classes路径
            //第一种:最常用,spring的配置文件路径以后就直接放在src
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

            //第二种方式:文件系统路径获得配置文件【绝对路径】
            //ApplicationContext context = new FileSystemXmlApplicationContext("C:\\Users\\Desktop\\IDEAWorkspace\\spring-01\\src\\com\\rookie\\beans.xml");

            //第三种方式:使用BeanFactory(了解)
            //String path = "C:\\Users\\Desktop\\IDEAWorkspace\\spring-01\\src\\com\\rookie\\beans.xml";
            //BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path));
            //IUserService user = (IUserService) factory.getBean("userService");
            //user.add();

            IUserService user = (IUserService) context.getBean("userService");
            user.add();
        }
    }

Spring内部创建对象的原理

a.解析xml文件,获取类名,id,属性等。

b.通过反射,用类型创建对象。

c.给创建的对象赋值。

2、BeanFactory 和 ApplicationContext对比

BeanFactory 采取延迟加载,第一次 getBean 时才会初始化 Bean。

ApplicationContext 是即时加载,对 BeanFactory 扩展,提供了更多功能。

  • 案例演示(在第一次的代码基础上)

    public class UserServiceImpl implements UserService {
    
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void add() {
            System.out.println("创建用户...." + name);
        }
    
        public UserServiceImpl(){
            System.out.println("UserServiceImpl() 调用了");
        }
    }
    public class ServiceTest {
    
        public static void main(String[] args) {
            //1.加载beans.xml 这个spring的配置文件,内部就会创建对象
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        }
    }

    控制台打印日志:UserServiceImpl( ) 调用了

    public class ServiceTest {
    
        public static void main(String[] args) {
            String path = "C:\\Users\\Desktop\\IDEAWorkspace\\spring-01\\src\\com\\rookie\\beans.xml";
    BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path));
    
            // 要使调用空参构造可以放开这段代码即可
            // IUserService user = (IUserService) factory.getBean("userService");
        }
    }

    控制台没有打印日志,说明空参构造没有被调用。

    放开上面注释的代码,即可调用空参构造,控制台打印日志:UserServiceImpl( ) 调用了。

2、Spring 容器装配 bean 的 3 种方式

所谓的装配bean就是在xml写一个bean标签。

<?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">

    <!--装配bean的三种方式,所谓的装配bean就是在xml写一个bean标签-->

    <!-- 第一种方式: new 实现类-->
    <bean id="userService1" class="com.example.demo.service.impl.UserServiceImpl">
        <property name="name" value="zhangsan"></property>
    </bean>

    <!-- 第二种方式:通过静态工厂方法 -->
    <bean id="userService2" class="com.example.demo.service.UserServiceFactory" factory-method="createUserService"/>

    <!--第三种方式:通过实例工厂方法 -->
    <bean id="factory2" class="com.example.demo.service.UserServiceFactory2"/>
    <bean id="userService3" factory-bean="factory2" factory-method="createUserService"/>
</beans>

测试上面哪种 bean 装配方式,需要注释掉其他 bean装配方式。

第一种上次已经讲过,现在只讲第二、三种案例。

public class UserServiceFactory {
    public static UserService createUserService() {
        return new UserServiceImpl();
    }
}

=========================================================================================
public class UserServiceFactory2 {
    public UserService createUserService() {
        return new UserServiceImpl();
    }
}

执行测试函数

public class ServiceTest {

    public static void main(String[] args) {

        //new 对象
        ApplicationContext context1 = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService1 = (UserService) context1.getBean("userService1");
        userService1.add();

        //静态工厂
        ApplicationContext context2 = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService2 = (UserService) context2.getBean("userService2");
        userService2.add();

        //实例工厂
        ApplicationContext context3 = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService3 = (UserService) context3.getBean("userService3");
        userService3.add();

    }
}

感兴趣的可以自己看执行结果。三种结果都证明 bean 被 Spring 容器管理实例化了。

3、bean的作用域(掌握 singleton、prototype)

类别 说明
singleton 在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在,默认值
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean()
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session 同一个HTTP Session 共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext 环境
globalSession 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext 环境

案例代码演示

bean.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.xsd">

    <bean id="userService1" class="com.example.demo.service.impl.UserServiceImpl" scope="prototype">
    </bean>
</beans>
public class ServiceTest {

    public static void main(String[] args) {

        ApplicationContext context1 = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService1 = (UserService) context1.getBean("userService1");
        UserService userService2 = (UserService) context1.getBean("userService1");
        System.out.println(userService1);
        System.out.println(userService2);
    }
}

控制台信息如下:

[email protected]
[email protected]

如果去掉 bean.xml 文件的 scope="prototype",打印信息如下:

[email protected]
[email protected]

所以Spring IoC容器Bean以单例方式默认存在!!配置的话根据自己需要配置单例或者多例

原文地址:https://www.cnblogs.com/miantiao312/p/11790089.html

时间: 2024-08-13 13:55:38

Spring 讲解(二 )的相关文章

Spring讲解二:Spring中的Bean配置1---基于XML文件的方式

一.在Spring的IOC容器中配置Bean 在xml文件中通过bean节点配置bean id:Bean的名称: (1) 在IOC容器中必须是唯一的 (2) 若id没有指定,Spring自动将权限限定性类名作为bean的名字 (3) id可以指定多个名字,名字之间可以用逗号.分号.或空格分隔 二.Spring容器 在Spring IOC容器读取Bean配置创建Bean实例之前,必须对它进行初始化.只有在容器实例化后,才可以从IOC容器中获取Bean实例并使用. Spring提供了两种类型的IOC

Spring讲解二:Spring中的Bean配置

一.IOC &DI 概述 IOC(Inversion of Control):思想是反转资源获取的方向.传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源.而应用IOC容器之后,则是容器主动的将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源.这种方式也被称为查找的被动形式. DI(Dependency Injection)--IOC的另一种表述方式:即组件以一些预先定义好的方式:如setter方法,接受来自如容器的资源注入.相对于IOC而言,这

spring3.1.1入门讲解二(注解篇)

在第一篇博客中主要讲解了如何搭建spring框架和运行示例项目:在本篇文章中主要讲解如何采用注解的方式简化开发! 一.准备篇-jar包的准备 这里就不详细说明了详见上一篇博客--spring3.1.1入门讲解一(非注解篇)中的准备篇讲解 二.环境搭建篇 1.在web.xml文件中添加的配置跟上一篇的配置代码一样,直接复制过去就行了. 2.配置spring-mvc.xml,重点就在这里 重点配置如下: 1).如果像我们采用非注解的方式去创建和访问controller控制器时,我们都需要在sprin

攻城狮在路上(贰) Spring(二)--- Spring IoC概念介绍

一.IoC的概念: IoC(控制反转)是Spring容器的核心.另一种解释是DI(依赖注入),即让调用类对某一个接口的依赖关系由第三方注入,以移除调用类对某一个接口实现类的一览. 定义如此,由此可见,在面向接口编程的情况下,IoC可以很好的实现解耦,可以以配置的方式为程序提供所需要的接口实现类. 在实际程序开发中,我们只需要提供对应的接口及实现类,然后通过Spring的配置文件或者注解完成对依赖类的装配.二.IoC的类型: 1.通过构造函数: 此种方式的缺点是,在构造函数中注入之后一般会作为一个

深入浅出Spring(二) IoC详解

上次的博客深入浅出Spring(一)Spring概述中,我给大家简单介绍了一下Spring相关概念.重点是这么一句:Spring是为了解决企业应用开发的复杂性而创建的一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.在这句话中重点有两个,一个是IoC,另一个是AOP.今天我们讲第一个IoC. IoC概念 控制反转(Inversion of Control)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题. 它还有一个名字叫做依赖注入(Dependency Injection)

HDSF主要节点讲解(二)工作原理

HDFS(Hadoop Distributed File System )Hadoop分布式文件系统.是根据google发表的论文翻版的.论文为GFS(Google File System)Google 文件系统(中文,英文). HDFS有很多特点: ① 保存多个副本,且提供容错机制,副本丢失或宕机自动恢复.默认存3份. ② 运行在廉价的机器上. ③ 适合大数据的处理.多大?多小?HDFS默认会将文件分割成block,64M为1个block.然后将block按键值对存储在HDFS上,并将键值对的

spring batch(二):核心部分(1):配置Spring batch

spring batch(二):核心部分(1):配置Spring batch 博客分类: Spring 经验 java chapter 3.Batch configuration 1.spring batch 的命名空间 spring xml中指定batch的前缀作为命名空间. 示例: Xml代码   <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sprin

【Java基础】Java面试题目整理与讲解(二)

1.Collection 和 Collections 的区别. Collection 是集合类的上级接口,继承于他的接口主要有 Set 和 List. Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作. 2.HashMap 和 Hashtable 的区别. HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,HashMap是非线程安全,效率上可能高于 Hashtable.在多个线程

Redis实战之征服 Redis + Jedis + Spring (二)

不得不说,用哈希操作来存对象,有点自讨苦吃! 不过,既然吃了苦,也做个记录,也许以后API升级后,能好用些呢?! 或许,是我的理解不对,没有真正的理解哈希表. 相关链接: Redis实战 Redis实战之Redis + Jedis Redis实战之征服 Redis + Jedis + Spring (一) Redis实战之征服 Redis + Jedis + Spring (二) Redis实战之征服 Redis + Jedis + Spring (三) 一.预期 接上一篇,扩充User属性: