每日学Java之一万个为什么?

新版jdbc路径com.mysql.cj.jdbc.Driver

SpringIOC容器和Tomcat Service容器相通之处和不同之处

相通之处

容器的概念:

两者都提供了一个“容器”的概念,用于管理和组织应用程序中的组件或对象。
容器负责创建、配置和管理这些组件或对象的生命周期。

依赖管理:

两种容器都涉及到某种形式的依赖管理。Spring IOC容器通过依赖注入(DI)来管理对象之间的依赖关系,而Tomcat容器则管理Web应用中各种资源和服务的依赖关系。

配置文件:

两者都可以通过配置文件进行定制化设置。Spring IOC容器通常使用XML配置文件或注解来进行配置,而Tomcat容器则使用server.xml、web.xml等配置文件。

生命周期管理:

两种容器都提供了对组件或对象生命周期的管理。例如,Spring IOC容器可以定义初始化和销毁方法,Tomcat容器则管理Servlet、Listener等组件的生命周期。

不同之处

功能定位:
Spring IOC容器:主要用于实现控制反转和依赖注入,帮助开发者更好地管理Java对象及其依赖关系。它是一个轻量级的应用框架,专注于业务逻辑层的组件管理。
Tomcat Service容器:是一个Servlet容器,主要负责处理HTTP请求和响应,运行并管理Web应用程序。它实现了Java EE的Servlet规范,支持JSP、Servlet等技术。
应用场景:
Spring IOC容器:适用于任何需要依赖注入和控制反转的Java应用,不仅限于Web应用。它可以与其他框架集成,如Spring MVC、Spring Boot等,也可以单独使用。
Tomcat Service容器:专门用于部署和运行基于Servlet API的Web应用程序,是Web服务器的一部分,处理客户端的HTTP请求。
依赖注入方式:
Spring IOC容器:通过构造函数注入、Setter方法注入、字段注入等方式实现依赖注入。
Tomcat Service容器:不直接提供依赖注入功能,而是通过Servlet规范中的ServletContext、ServletConfig等接口来传递配置信息和资源引用。
扩展性和灵活性:
Spring IOC容器:高度灵活且可扩展,支持多种配置方式(如XML、注解、Java Config),并且可以通过AOP、事件机制等增强功能。
Tomcat Service容器:虽然也具有一定的扩展性(如通过Valve、Filter等机制),但在灵活性上不如Spring IOC容器,更多地遵循Java EE标准。
生命周期管理的具体内容:
Spring IOC容器:管理的是Spring Bean的生命周期,包括初始化、销毁等阶段,可以通过接口如InitializingBean、DisposableBean或者注解@PostConstruct、@PreDestroy来定制这些阶段的行为。
Tomcat Service容器:管理的是Servlet、Listener、Filter等Web组件的生命周期,按照Servlet规范定义的标准生命周期回调方法(如init()、destroy())进行管理。

线程模型:

Spring IOC容器:本身并不直接涉及多线程问题,线程管理通常是应用程序代码的责任。

Tomcat Service容器:内置了线程池来处理并发请求,每个请求通常在一个独立的线程中处理。
配置与部署:
Spring IOC容器:配置文件通常位于项目的classpath下,如applicationContext.xml或@Configuration类。
Tomcat Service容器:配置文件通常位于Tomcat安装目录下的conf文件夹中,如server.xml、web.xml等,并且Web应用需要打包为WAR文件部署到Tomcat中。

为什么需要FactoryBean

Bean标签中只能注入引用和初始值
对于复杂对象(第三方代理类创建的,就是说不能直接new出来,要间接获得的),使用FactoryBean接口示例getObject方法去获取
作为三级缓存,处理AOP

FactoryBean 和 BeanFactory区别

FactoryBean 重点在于Bean 说明这是一个创建Bean的工厂

BeanFactory 重点在于Factory 说明这是管理Bean的工厂就是IOC

多例可以帮助高并发吗?

tomcat中我们知道sevlet一个人就可以处理相关请求。事实上某种servlet的service方法会被分裂到tomcat多线程的本地栈中。那么多个servlet 和 多线程是没有关系的
同理,Spring中的prototype 多例跟多线程也没什么关系。

补充:多例和单例的创建时机就好像实例方法和类方法,一个用到才创建,一个在类加载的时候被创建。所以单例是容器加载的(初始化)时候被创建。 多例是getBean()创建。

Bean的life cycle

  • 1.加载Bean定义信息

    • XML读取
    • 转换为BeanDefinition对象
    • 存储BeanDefinition,等待实例化
  • 2.实例化Bean组件

    • 实例化
    • 先实例化被依赖的Bean
    • 不会进行属性赋值
  • 3.设置Bean属性

    • 注入属性值
    • 避免组件声明先后顺序问题
    • 解决了循环依赖
  • 4.调用Bean初始化方法

    • 如果Bean实现了InitializingBean接口,Spring调用after Properties Set()方法
    • 如果定义了init-method,将执行该方法
    • 自定义方法,类似servlet.init()。常见自定义:比如FactroyBean的实现
  • 5.Bean可以使用

    1. 调用Bean的销毁方法(仅适用于单例Bean)
    • 如果Bean实现了DisposableBean接口,Spring将调用其destroy()方法
    • 如果在XML配置中定义了destroy-method,则执行该方法。
    • 如果Bean使用了@PreDestroy注解,则在销毁之前执行被注解的方法,此阶段调用自定义销毁方法,可以进行相关的资源释放工作,类似:Servlet的destroy方法。

Spring在Bean的生命周期扩展接口(允许你强化组件)(Spring用接口造了一面墙)

将业务层的组件对象交给IOC容器管理,他就会自动帮你添加事务代码
怎么做到的?

Spring提供了一些外置接口,允许开发者在加载过程中进行自定义的插入和扩展:

  • 1.Interface- BeanFactoryPostProcessor:

    • 在容器实例化任何Bean之前,允许对BeanDefinition进行修改。可以用于动态修改Bean配置,或者注册新的BeanDefinition。
    • 调用时机在 阶段一和阶段二之间,已经获取BeanDefinition。
    • Bean设置属性时读取外部配置就利用此接口进行扩展($(key}->替换>>对应的具体参数值)
  • 2.Interface- BeanPostProcessor:

    • 提供了两个方法,postProcessBeforeInitialization()和postProcessAfterinitialization(),允许在Bean初始化前后进行自定义操作。
    • 调用时机在阶段三四之间和阶段四五之间。
    • 可以进行Bean实例化后的扩展,后面要讲解的AOP就是利用此接口进行实现。

3.其他接口(了解):

BeanDefinitionRegistryPostProcessor接口*:用于处理Bean定义的注册过程,允许对Bean定义进行修改、补充或删除。功能与BeanFactoryPostProcessor接口类似!

Aware系列接囗:提供了BeanNameAware、BeanFactoryAware和ApplicationContextAware等接口,允许Bean在被容器实例化后获取与容器相关的信息!

测试BeanFactoryPostProcessor和BeanPostProcessor方法之后发现这两个接口的实现会扫描核心容器全局组件

AOP实现

XML配置Bean的缺点

1.标签比较麻烦
2.属性前置要求有set方法

引入 注解+XML配置(Spring2.0更新的IOC/DI注解)

Spring2.0优化了自定义类

对象加入容器,对象赋值

1.自定义类加入容器 UserService

  • @Component == <bean id= class=“当前类”

2.自定义类的属性赋值

之前需要给成员变量赋值设置set通道,引用要加ref标签

  • @Value() == <property
  • @Autowired == <property ref

3.第三方jar包的类DruidDataSource (jar包只读,不能带注解怎么办):写Bean标签

4.第三方类的属性 还是得写标签

5.引入外部的配置文件 <context:

6.扫描包的标签<context:component-scan

弱警告:不推荐使用@Autowired 字段注入

ComponentScan路径原则

尽量精准,范围越小越好,可以写多个包

SpringFramework阶段注解功能都是为了加载Bean怎么理解

常见的 Spring 生命周期注解
@PostConstruct
@PreDestroy
@Bean
@Component, @Service, @Repository, @Controller
@Configuration
@Scope
@Lazy
@DependsOn

详细解释

  1. @PostConstruct 和 @PreDestroy
    @PostConstruct:
    在依赖注入完成后立即调用。
    通常用于初始化资源或执行一些设置操作。
    @PreDestroy:
    在 Bean 销毁之前调用。
    通常用于释放资源或执行清理操作。
    示例代码:
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class MyBean {

    @PostConstruct
    public void init() {
        System.out.println("MyBean initialized");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("MyBean destroyed");
    }
}
  1. @Bean
    @Bean:
    用于在配置类中定义一个 Bean。
    返回的对象会被注册到 Spring 容器中。
    示例代码:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}
  1. 组件扫描注解 (@Component, @Service, @Repository, @Controller)
    @Component: 通用注解,表示一个组件。
    @Service: 表示服务层组件。
    @Repository: 表示数据访问层组件。
    @Controller: 表示控制器层组件。
    这些注解标记的类会被 Spring 自动检测并注册为 Bean。

示例代码:

import org.springframework.stereotype.Component;

@Component
public class MyComponent {
    // 类实现
}
  1. @Configuration
    @Configuration:
    标记一个类作为配置类。
    配置类可以包含多个 @Bean 方法来定义 Bean。
    示例代码:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}
  1. @Scope
    @Scope:
    控制 Bean 的作用域。
    常见的作用域包括 singleton(默认)、prototype、request、session 等。
    示例代码:
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrototypeBean {
    // 类实现
}
  1. @Lazy
    @Lazy:
    延迟 Bean 的初始化。
    默认情况下,Spring 在启动时会初始化所有单例 Bean。使用 @Lazy 可以延迟 Bean 的初始化直到第一次请求时。
    示例代码:
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy
public class LazyBean {
    // 类实现
}
  1. @DependsOn
    @DependsOn:
    指定 Bean 的依赖关系。
    确保某个 Bean 在另一个 Bean 初始化之前被初始化。
    示例代码:
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

@Component
@DependsOn("anotherBean")
public class DependentBean {
    // 类实现
}

@Component
public class AnotherBean {
    // 类实现
}

如何理解这些注解的功能
Bean 的创建和初始化:
@Bean: 定义 Bean 并将其注册到容器中。
@Component, @Service, @Repository, @Controller: 自动检测并注册为 Bean。
@Configuration: 提供配置类来定义多个 Bean。
生命周期管理:
@PostConstruct: 在依赖注入完成后执行初始化操作。
@PreDestroy: 在 Bean 销毁前执行清理操作。
作用域控制:
@Scope: 控制 Bean 的作用域(如单例、原型等)。
延迟加载:
@Lazy: 延迟 Bean 的初始化直到首次请求。
依赖关系管理:
@DependsOn: 明确指定 Bean 的依赖关系,确保正确的初始化顺序。

AppConfig 类:
使用 @Configuration 注解标记为配置类。
定义了两个 Bean:myBean 和 prototypeBean。
MyComponent 类:
使用 @Component 注解标记为 Bean。
注入了 MyBean 和 LazyBean。
使用 @PostConstruct 和 @PreDestroy 进行初始化和销毁操作。
MyBean 类:
使用 @Component 注解标记为 Bean。
使用 @PostConstruct 和 @PreDestroy 进行初始化和销毁操作。
PrototypeBean 类:
使用 @Component 和 @Scope(“prototype”) 注解标记为原型 Bean。
使用 @PostConstruct 和 @PreDestroy 进行初始化和销毁操作。
LazyBean 类:
使用 @Component 和 @Lazy 注解标记为延迟加载 Bean。
使用 @PostConstruct 和 @PreDestroy 进行初始化和销毁操作。
MainApp 类:
创建 AnnotationConfigApplicationContext 上下文并加载配置类。
获取并使用 MyComponent, PrototypeBean, 和 LazyBean。
关闭上下文以触发 Bean 的销毁操作。

@Bean: 定义并注册 Bean 到 Spring 容器。
@Component, @Service, @Repository, @Controller: 自动检测并注册为 Bean。
@Configuration: 提供配置类来定义多个 Bean。
@PostConstruct: 在依赖注入完成后执行初始化操作。
@PreDestroy: 在 Bean 销毁前执行清理操作。
@Scope: 控制 Bean 的作用域。
@Lazy: 延迟 Bean 的初始化。
@DependsOn: 指定 Bean 的依赖关系。
通过这些注解,Spring Framework 提供了一种灵活且强大的方式来管理和控制 Bean 的生命周期,确保应用程序的各个部分按预期工作。

Spring中的注解继承关系

@Resource 及其 JSR250 与 @Autowired区别

@Value 配置中心联动

配置类引入+@Bean 替代了 XML加载第三方jar包中的类

提供了xml中 bean标签的所有设置
会将目标方法的返回对象名作为组件ID使用
原作用域标签更换为 @Scope注解

配置类加载properties

通过@Properties注解 扫描目标路径文件,通过@Value加载
@Value的好处就是既不用写XML 还能用 通配符

配置类中@Bean自定义类装配 和 配置类@ComponentScan在自定义类上扫描@Service@Repository等等注解装配有什么区别

@Bean

@Bean->返回值->ioc容器中
细节1:
组件的名称默认:方法名 修改:

  • 1.改方法名
  • 2.@Bean(namelvalue)

细节2:
如何设置方法1、接口法解了.xml init-methodldestroy-method 4.@Bean(initMethoddestroyMethod =“方法”)

细节3:如何设置单例还是多网*

细节4:如何设置菲引用类型的值(外部的配置参数)

方案1:据置类中声明变量+@Value注解
方案2:在Bean的形参列表中引入(Value(“${jdbc.url}”)Stringurl)
细书5:期何设置引用类型的值

@Bean方法的形参列表(其他组件类型对象名)-》核心容器会自动按照类型注入(@Autowired)1.没存类型报错NoSuchBeanDefinition
2、如果有,且有多个类望,先根据形参名进行匹配,匹不到才报错

@SpringJUnitConfig(value = 配置类.class)

相当于创建了IOC容器

今天写了一个死循环

while(allStudentQuery.iterator().hasNext()){
                System.out.println(allStudentQuery.iterator().next());
            }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

~Yogi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值