当前位置: 首页 > news >正文

织梦网站支付安装怎么去推广自己的店铺

织梦网站支付安装,怎么去推广自己的店铺,优秀企业官网设计案例,建设注册管理中心网站从零手写Spring IoC容器(二):bean的定义与注册 一. 回顾简单容器的不足之处 在第一章中,我们实现了一个最简单的 IoC 容器,但该版本存在诸多不足,例如: Bean 的管理方式过于简单,…

从零手写Spring IoC容器(二):bean的定义与注册

一. 回顾简单容器的不足之处

在第一章中,我们实现了一个最简单的 IoC 容器,但该版本存在诸多不足,例如:

  • Bean 的管理方式过于简单,无法描述 Bean 之间的依赖关系。
  • 缺少 Bean 作用域的管理,无法区分单例(singleton)和原型(prototype)。
  • 无法设置 Bean 的属性,不能进行依赖注入。
  • 没有生命周期管理,无法进行初始化与销毁操作。

为了克服上述缺陷,我们需要引入 Bean 的定义与注册机制

二. 问题分析

1. 如何描述 Bean?

为了更灵活地管理 Bean,我们需要对其进行更详细的描述:

  • 类信息(Bean 的具体实现类)
  • 配置信息(属性值、环境相关配置)
  • 依赖关系(需要注入哪些其他 Bean)
2. 如何管理 Bean 的定义?

IoC 容器不仅需要存储 Bean,还需要提供完善的管理机制:

  • 统一注册机制:能够注册、移除、获取 Bean 定义。
  • 运行时切换:支持不同的 Bean 作用域,例如单例(singleton)或原型(prototype)。
  • 依赖分析和注入:支持属性注入,确保 Bean 能够正确构造。

三. 设计 BeanDefinition

我们先设计 BeanDefinition 接口来描述 Bean:

  • 包含 Bean 的完整信息
  • 支持属性配置
  • 支持作用域管理
  • 支持生命周期方法

1.设计BeanDefinition 接口

package com.fth.beans.factory.config;/*** 用于描述 Bean 的定义*/
public interface BeanDefinition {// Bean 作用域常量String SCOPE_SINGLETON = "singleton";String SCOPE_PROTOTYPE = "prototype";// 基本信息void setBeanClass(Class<?> beanClass);Class<?> getBeanClass();// 作用域void setScope(String scope);String getScope();boolean isSingleton();boolean isPrototype();// 是否延迟初始化void setLazyInit(boolean lazyInit);boolean isLazyInit();// 生命周期方法void setInitMethodName(String initMethodName);String getInitMethodName();void setDestroyMethodName(String destroyMethodName);String getDestroyMethodName();// 属性void setPropertyValues(PropertyValues propertyValues);PropertyValues getPropertyValues();
}
2. PropertyValuePropertyValues

PropertyValue 用于存储单个 Bean 属性的信息,而 PropertyValues 作为容器,存储 Bean 的所有属性。

package com.fth.beans.factory.config;/*** Bean 属性值的封装类*/
public class PropertyValue {private final String name;private final Object value;private final Class<?> type;/*** 创建一个新的 PropertyValue 实例*/public PropertyValue(String name, Object value, Class<?> type) {if (name == null || name.isEmpty()) {throw new IllegalArgumentException("Property name must not be null or empty");}this.name = name;this.value = value;this.type = type;}/*** 不指定类型的 PropertyValue 构造方法*/public PropertyValue(String name, Object value) {this(name, value, value != null ? value.getClass() : Object.class);}public String getName() {return this.name;}public Object getValue() {return this.value;}public Class<?> getType() {return this.type;}@Overridepublic boolean equals(Object other) {if (this == other) {return true;}if (!(other instanceof PropertyValue)) {return false;}return this.name.equals(((PropertyValue) other).name);}@Overridepublic int hashCode() {return this.name.hashCode();}@Overridepublic String toString() {return "PropertyValue: name='" + this.name + "', value=[" + this.value + "]";}
}

3.实现BeanDefinition

GenericBeanDefinitionBeanDefinition 的一个具体实现,用于存储 Bean 的元数据。

package com.fth.beans.factory.support;import com.fth.beans.factory.config.BeanDefinition;
import com.fth.beans.factory.config.PropertyValues;/*** 通用 BeanDefinition 实现*/
public class GenericBeanDefinition implements BeanDefinition {private Class<?> beanClass;private String scope = SCOPE_SINGLETON;private boolean lazyInit = false;private String initMethodName;private String destroyMethodName;private PropertyValues propertyValues = new PropertyValues();@Overridepublic void setBeanClass(Class<?> beanClass) {this.beanClass = beanClass;}@Overridepublic Class<?> getBeanClass() {return this.beanClass;}@Overridepublic void setScope(String scope) {this.scope = scope;}@Overridepublic String getScope() {return this.scope;}@Overridepublic boolean isSingleton() {return SCOPE_SINGLETON.equals(this.scope);}@Overridepublic boolean isPrototype() {return SCOPE_PROTOTYPE.equals(this.scope);}@Overridepublic void setLazyInit(boolean lazyInit) {this.lazyInit = lazyInit;}@Overridepublic boolean isLazyInit() {return this.lazyInit;}@Overridepublic void setInitMethodName(String initMethodName) {this.initMethodName = initMethodName;}@Overridepublic String getInitMethodName() {return this.initMethodName;}@Overridepublic void setDestroyMethodName(String destroyMethodName) {this.destroyMethodName = destroyMethodName;}@Overridepublic String getDestroyMethodName() {return this.destroyMethodName;}@Overridepublic void setPropertyValues(PropertyValues propertyValues) {this.propertyValues = propertyValues;}@Overridepublic PropertyValues getPropertyValues() {return this.propertyValues;}
}

四. 设计 BeanDefinitionRegistry

为了注册和管理 Bean 定义,我们设计 BeanDefinitionRegistry 接口:

package com.fth.beans.factory.support;import com.fth.beans.factory.config.BeanDefinition;/*** BeanDefinition 注册表*/
public interface BeanDefinitionRegistry {void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);void removeBeanDefinition(String beanName);BeanDefinition getBeanDefinition(String beanName);boolean containsBeanDefinition(String beanName);String[] getBeanDefinitionNames();int getBeanDefinitionCount();
}

五.实现第二版 IoC 容器

我们现在基于 BeanDefinitionBeanDefinitionRegistry 来实现一个基本的 IoC 容器,支持手动注册 BeanDefinition,并能够根据 BeanDefinition 创建 Bean 实例,同时支持 单例原型 两种作用域。

1. 设计 DefaultBeanFactory

DefaultBeanFactory 负责:

  • 维护 BeanDefinition 的注册表
  • 根据 BeanDefinition 创建 Bean
  • 处理单例和原型作用域
package com.fth.beans.factory.support;import com.fth.beans.BeansException;
import com.fth.beans.factory.BeanFactory;
import com.fth.beans.factory.config.BeanDefinition;
import com.fth.beans.factory.config.BeanDefinitionRegistry;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 默认 Bean 工厂,负责管理 BeanDefinition 和 Bean 实例*/
public class DefaultBeanFactory implements BeanDefinitionRegistry, BeanFactory {// 存储 BeanDefinitionprivate final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();// 存储单例 Beanprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();// === 实现 BeanDefinitionRegistry ===@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);// 如果是单例且非懒加载,则立即创建实例if (beanDefinition.isSingleton() && !beanDefinition.isLazyInit()) {singletonObjects.put(beanName, createBean(beanDefinition));}}@Overridepublic void removeBeanDefinition(String beanName) {beanDefinitionMap.remove(beanName);singletonObjects.remove(beanName);}@Overridepublic BeanDefinition getBeanDefinition(String beanName) {return beanDefinitionMap.get(beanName);}@Overridepublic boolean containsBeanDefinition(String beanName) {return beanDefinitionMap.containsKey(beanName);}@Overridepublic String[] getBeanDefinitionNames() {return beanDefinitionMap.keySet().toArray(new String[0]);}@Overridepublic int getBeanDefinitionCount() {return beanDefinitionMap.size();}// === 实现 BeanFactory ===@Overridepublic Object getBean(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);if (beanDefinition == null) {throw new BeansException("No bean named '" + name + "' is defined");}if (beanDefinition.isSingleton()) {return singletonObjects.computeIfAbsent(name, k -> createBean(beanDefinition));}return createBean(beanDefinition);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {Object bean = getBean(name);if (!requiredType.isInstance(bean)) {throw new BeansException("Bean named '" + name + "' is not of type " + requiredType.getName());}return requiredType.cast(bean);}@Overridepublic <T> T getBean(Class<T> requiredType) throws BeansException {for (String beanName : beanDefinitionMap.keySet()) {Object bean = getBean(beanName);if (requiredType.isInstance(bean)) {return requiredType.cast(bean);}}throw new BeansException("No bean of type " + requiredType.getName() + " is defined");}@Overridepublic boolean containsBean(String name) {return beanDefinitionMap.containsKey(name);}@Overridepublic boolean isSingleton(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return beanDefinition != null && beanDefinition.isSingleton();}@Overridepublic boolean isPrototype(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return beanDefinition != null && beanDefinition.isPrototype();}@Overridepublic Class<?> getType(String name) throws BeansException {BeanDefinition beanDefinition = getBeanDefinition(name);return (beanDefinition != null) ? beanDefinition.getBeanClass() : null;}/*** 根据 BeanDefinition 创建 Bean 实例*/private Object createBean(BeanDefinition beanDefinition) {try {// 获取无参构造函数Constructor<?> constructor = beanDefinition.getBeanClass().getDeclaredConstructor();constructor.setAccessible(true);  // 设置可访问return constructor.newInstance();  // 使用构造函数创建实例} catch (Exception e) {throw new RuntimeException("Failed to create bean: " + beanDefinition.getBeanClass(), e);}}
}

2.测试使用

package com.fth.test;import com.fth.beans.factory.BeanFactory;
import com.fth.beans.factory.support.DefaultBeanFactory;
import com.fth.beans.factory.support.GenericBeanDefinition;/*** 测试 IoC 容器*/
public class BeanFactoryTest {public static void main(String[] args) {// 创建 BeanFactoryDefaultBeanFactory beanFactory = new DefaultBeanFactory();// 注册一个单例 BeanGenericBeanDefinition singletonDefinition = new GenericBeanDefinition();singletonDefinition.setBeanClass(TestService.class);singletonDefinition.setScope(GenericBeanDefinition.SCOPE_SINGLETON);beanFactory.registerBeanDefinition("testService", singletonDefinition);// 获取单例 BeanTestService service1 = beanFactory.getBean("testService", TestService.class);TestService service2 = beanFactory.getBean("testService", TestService.class);System.out.println("service1 == service2: " + (service1 == service2)); // true// 注册一个原型 BeanGenericBeanDefinition prototypeDefinition = new GenericBeanDefinition();prototypeDefinition.setBeanClass(TestService.class);prototypeDefinition.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);beanFactory.registerBeanDefinition("prototypeService", prototypeDefinition);// 获取原型 BeanTestService proto1 = beanFactory.getBean("prototypeService", TestService.class);TestService proto2 = beanFactory.getBean("prototypeService", TestService.class);System.out.println("proto1 == proto2: " + (proto1 == proto2)); // false}
}/*** 测试用 Bean*/
class TestService {public void sayHello() {System.out.println("Hello from TestService!");}
}

六.与Spring的对比与下一步实现

与Spring的对比

1. Bean 的注册与获取
  • Spring:
    • Spring 使用 ApplicationContext 来管理 Bean。
    • Bean 的定义可以通过注解、XML 配置或者 Java 配置类来进行。
    • ApplicationContext 允许根据名称或类型来获取 Bean,并且支持 Bean 的自动装配。
  • 自定义 IoC 容器:
    • 在自定义容器中,我们通过手动注册 BeanDefinitionBeanFactory 来管理 Bean。
    • 目前的实现只能通过名称获取单个 Bean,且只支持单例和原型的基本功能。
2. Bean 的生命周期管理
  • Spring:
    • Spring 提供了丰富的生命周期管理功能,例如:
      • 初始化方法:支持 @PostConstruct 注解、init-method 属性等。
      • 销毁方法:支持 @PreDestroy 注解、destroy-method 属性等。
      • BeanPostProcessor:可以在 Bean 初始化前后执行特定操作。
      • ApplicationContextAware、BeanFactoryAware 等:使 Bean 可以访问容器的相关信息。
  • 自定义 IoC 容器:
    • 当前实现没有处理 Bean 的初始化、销毁等生命周期管理,功能相对简单,主要关注 Bean 的创建和作用域(单例、原型)。
3. 作用域管理
  • Spring:
    • Spring 支持多种作用域,包括:
      • singleton(默认):每个 Bean 在容器中只有一个实例。
      • prototype:每次请求都会返回一个新的 Bean 实例。
      • request, session, application 等:在 Web 环境下,Spring 支持更多基于 HTTP 请求的作用域。
  • 自定义 IoC 容器:
    • 当前实现仅支持 singletonprototype 两种作用域。
4. 自动装配与依赖注入
  • Spring:
    • Spring 支持基于注解(如 @Autowired)和 XML 配置的自动装配。
    • 可以自动解析 Bean 之间的依赖关系,通过构造函数、Setter 或字段注入方式注入依赖。
  • 自定义 IoC 容器:
    • 当前版本没有实现依赖注入和自动装配,需要手动处理 Bean 的依赖关系。

下一步安排:Bean 的生命周期管理

为了让自定义的 IoC 容器更加完善,下一步实现 Bean 的生命周期管理,这包括以下几个方面:

1. 初始化与销毁
  • 初始化方法:可以为每个 Bean 定义一个初始化方法,在 Bean 创建后、依赖注入完成后执行。
  • 销毁方法:可以为每个 Bean 定义销毁方法,在 Bean 被销毁前执行,释放资源。
2. 添加 BeanPostProcessor 机制

Spring 提供了 BeanPostProcessor 接口,允许开发者在 Bean 初始化前后执行特定操作。你可以在自定义容器中实现类似机制:

  • 初始化前:在 Bean 实例化后、依赖注入前执行。
  • 初始化后:在 Bean 初始化完成后执行。

文章转载自:
http://dinncopaulette.tpps.cn
http://dinncomoondoggle.tpps.cn
http://dinncotharm.tpps.cn
http://dinncoflorentine.tpps.cn
http://dinncopipeful.tpps.cn
http://dinncoarrester.tpps.cn
http://dinncozoologic.tpps.cn
http://dinncodiarchial.tpps.cn
http://dinncobearcat.tpps.cn
http://dinncoerector.tpps.cn
http://dinncoexploded.tpps.cn
http://dinncochorine.tpps.cn
http://dinncoequijoin.tpps.cn
http://dinncoennead.tpps.cn
http://dinncomatilda.tpps.cn
http://dinncochemigrapher.tpps.cn
http://dinncocreamer.tpps.cn
http://dinncojesse.tpps.cn
http://dinncococainism.tpps.cn
http://dinncocutaneous.tpps.cn
http://dinncopaddlefish.tpps.cn
http://dinncosigmoidectomy.tpps.cn
http://dinncoointment.tpps.cn
http://dinncooverbore.tpps.cn
http://dinncobarbasco.tpps.cn
http://dinncomavourneen.tpps.cn
http://dinncodirectional.tpps.cn
http://dinncorossby.tpps.cn
http://dinncospecimen.tpps.cn
http://dinncogigman.tpps.cn
http://dinncoplaid.tpps.cn
http://dinnconipa.tpps.cn
http://dinncoastrosphere.tpps.cn
http://dinncoyarrow.tpps.cn
http://dinncorepat.tpps.cn
http://dinncousphs.tpps.cn
http://dinncohydrometry.tpps.cn
http://dinncocreator.tpps.cn
http://dinncoshrift.tpps.cn
http://dinncoemigration.tpps.cn
http://dinncotaut.tpps.cn
http://dinncoshoreward.tpps.cn
http://dinncoerectile.tpps.cn
http://dinncofucking.tpps.cn
http://dinncostereopticon.tpps.cn
http://dinncorotenone.tpps.cn
http://dinncodecarbonate.tpps.cn
http://dinncoout.tpps.cn
http://dinncoautocephaly.tpps.cn
http://dinncovirtually.tpps.cn
http://dinncowinner.tpps.cn
http://dinncoflamenco.tpps.cn
http://dinncoeverywhither.tpps.cn
http://dinncocancerogenic.tpps.cn
http://dinncobeehive.tpps.cn
http://dinncodemagoguism.tpps.cn
http://dinncohandplay.tpps.cn
http://dinncoleggy.tpps.cn
http://dinncopean.tpps.cn
http://dinncomanorial.tpps.cn
http://dinncobrachydactylous.tpps.cn
http://dinncomessidor.tpps.cn
http://dinncotetramisole.tpps.cn
http://dinncoeconomize.tpps.cn
http://dinncogoan.tpps.cn
http://dinncomultipage.tpps.cn
http://dinncoclincher.tpps.cn
http://dinncofm.tpps.cn
http://dinncotenseless.tpps.cn
http://dinncowicketkeeper.tpps.cn
http://dinncojargon.tpps.cn
http://dinncospaceplane.tpps.cn
http://dinncocumbrous.tpps.cn
http://dinncobookstack.tpps.cn
http://dinncofeudal.tpps.cn
http://dinncomam.tpps.cn
http://dinncoinapposite.tpps.cn
http://dinncoaplanat.tpps.cn
http://dinncopome.tpps.cn
http://dinncomecopteran.tpps.cn
http://dinncosanguinivorous.tpps.cn
http://dinncoteacher.tpps.cn
http://dinncomarg.tpps.cn
http://dinncomammet.tpps.cn
http://dinncopudge.tpps.cn
http://dinncomovement.tpps.cn
http://dinncoflaked.tpps.cn
http://dinncoyahata.tpps.cn
http://dinncodiscoverable.tpps.cn
http://dinncobikky.tpps.cn
http://dinncofrypan.tpps.cn
http://dinncodunny.tpps.cn
http://dinncokinglake.tpps.cn
http://dinncohandbound.tpps.cn
http://dinncobaronage.tpps.cn
http://dinncoventrotomy.tpps.cn
http://dinncosparge.tpps.cn
http://dinncojokiness.tpps.cn
http://dinncodechristianize.tpps.cn
http://dinncocontrolment.tpps.cn
http://www.dinnco.com/news/146304.html

相关文章:

  • 兰州建网站今日热点新闻头条排行榜
  • 网站开发遇到什么问题西安专业网络推广平台
  • WordPress多种类文件上传绍兴seo
  • 深圳优质网站建设案例百度app广告
  • 网站demo制作谷歌建站
  • 深圳定制网站制作北京seo顾问
  • 什么网站做聚乙烯醇好的sem工作原理
  • 电子商务网站设计与实现论文优化大师怎么提交作业
  • 建站程序的价钱有域名了怎么建立网站
  • 公司做竞拍网站的收入怎么报税微信运营方案
  • 怎么新增网站推广快速优化工具
  • 功能型网站建设响应式网站模板的特点
  • 找网站建设工作室靠谱吗网站维护一般怎么做
  • wordpress添加熊掌号谷歌搜索优化seo
  • 网站建设公司商务网站项目书鹤壁seo推广
  • w3c网站怎么做长沙百度快速优化排名
  • 广州建站业务公司如何制作付费视频网站
  • 备案成功后怎么做网站网络服务器是指什么
  • 一个空间可以放两个网站吗谷歌搜索引擎入口2021
  • 网站开发内容seo搜索引擎优化关键词
  • 呼和浩特做网站公司小程序自助搭建平台
  • 毕业设计开题报告网站开发618网络营销策划方案
  • 网站建设同步视频百度助手下载
  • 个人主页自助建站短视频询盘获客系统
  • 章丘哪里做网站公司网络推广排名定制
  • 百度网站怎么做友情链接软文推荐
  • wordpress默认原始图片长沙网站托管seo优化公司
  • 祖庙网站建设抖音关键词搜索排名收费
  • 网站建设的销售好做吗最近的电脑培训班在哪里
  • 湖南长沙市芙蓉区疫情最新消息成都网站seo排名优化