【程序员不圆2】【Spring2】Bean的探究1

364 阅读4分钟

Bean的探究1

提到Spring总会有老哥们Bean,Context,Core三套打过来

但是Spring用过不少了,感觉好像没有用到过上面三个核心?

那么今天就从零开始探究

没有Bean行不行?没有Context行不行?

什么是Bean

我觉得一般这种时候举例是最好的,举一个Bean的例子不就啥都懂了吗

写一个Bean

定义一个 HelloWorld 类

package com.tutorialspoint;
public class HelloWorld {
   private String message;
   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

配置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-3.0.xsd">

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>

写Main函数

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
   }
}

为什么要用Bean

可以看到最简单的原因就是

构造函数和代码解耦

深究一下

ApplicationContext干了什么

ApplicationContext就是常说的Spring容器???

创建BeanFactory

创建Bean

getBean干了什么

获取一个Bean的实例

根据doGetBean方法,简单来说

  1. 从缓存中获取Bean
  2. 如果缓存中没有,循环获取父Bean,递归生成Bean
  3. 根据score看是单例还是原型
  4. 返回Bean

要是我不用Bean来管理new出来的对象呢?

在doGetBean中可以看到,他可以自动的递归创建对象,不用手动new

手动new就需要复杂的构造函数 和 多个new

怎么让Spring知道这是一个Bean?

三种方法:XML,注解,Java类

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

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>

注解

用注解配置 等价上面的XML

注解解释
@Controller组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上。
@Service组合注解(组合了@Component注解),应用在service层(业务逻辑层)
@Reponsitory组合注解(组合了@Component注解),应用在dao层(数据访问层)
@Component表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component还是一个元注解。

Java类

用代码配置Bean

注解解释
@Configuration配置类
@Bean该方法名默认就是Bean的名称,该方法返回值就是Bean的对象
@Configuration
public class ApplicationContextConfig {
    @Bean
    public String message() {
        return "hello";
    }
}

为什么要Spring容器管理Bean?

什么是Spring容器

一个Spring容器就是某个实现了ApplicationContext接口的类的实例

Spring容器就是一个Bean工厂

Bean的实例化,获取,销毁等都是由这个bean工厂

我们必须明确,Spring的核心是容器,而容器并不唯一,框架本身就提供了很多个容器的实现,大概分为两种类型:一种是不常用的BeanFactory,这是最简单的容器,只能提供基本的DI功能;还有一种就是继承了BeanFactory后派生而来的应用上下文,其抽象接口也就是我们上面提到的的ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。

为什么总喜欢问Bean的作用域

Bean的作用域

  • singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  • session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
  • global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

那么为什么?

首先,默认单例,因为

  • 像Service,Controller这样的Bean,确实只需要一个就够了,调用其中的方法,不会有线程问题
  • 如果每次都New一个,内存开销很大

选择不同的作用域,对应不同的场景

  • singleton:没有状态的Bean,需要在服务器中永久存活
  • prototype:满状态的Bean,生命很短,朝生暮死
  • request:需要一个请求一个状态,存活时间不需要太长
  • session:一个会话才一个状态,存活时间和session时间保持一致

恍然大悟

回到开头的问题,没有Bean行吗?

行,那么Spring这个框架到底牛在哪里,是不是必须要用他?

是不是可以将Spring理解为:

  • 一个最基本的Web服务器
  • IOC用来管理Bean
  • AOP用来面向切面编程
  • 数据库获取事务等
  • 测试功能
  • 各种其他的便于整合的工具集合(Springboot)

参考资料

www.w3cschool.cn/wkspring/dg…

blog.csdn.net/weixin_3749…

blog.csdn.net/icarus_wang…

blog.csdn.net/u014199143/…

zhuanlan.zhihu.com/p/68701674

my.oschina.net/javaFamily/…

www.nowcoder.com/discuss/360…