九江网站建设优化,网站前台的网址,建筑用网包括哪些,网站设计和建设自考题Spring学习笔记#xff08;2#xff09; 一、Spring配置非定义Bean1.1 DruidDataSource1.2、Connection1.3、Date1.4、SqlSessionFactory 二、Bean实例化的基本流程2.1 BeanDefinition2.2 单例池和流程总结 三、Spring的bean工厂后处理器3.1 bean工厂后处理器入门3.2、注册Be… Spring学习笔记2 一、Spring配置非定义Bean1.1 DruidDataSource1.2、Connection1.3、Date1.4、SqlSessionFactory 二、Bean实例化的基本流程2.1 BeanDefinition2.2 单例池和流程总结 三、Spring的bean工厂后处理器3.1 bean工厂后处理器入门3.2、注册BeanDefinition3.3、BeanDefinitionRegistryPostProcessor3.4 完善实例化流程图3.5、自定义Component 四、Spring的Bean后处理器4.1 概念和入门4.2 当中的一些调用方法的顺序4.3 更加详细的实例化基本操作 五、Spring的生命周期5.1 概述5.2 初始化阶段执行的步骤5.3 初始化阶段注入属性信息封装5.4、属性注入的三种情况5.4.1 单项注入的代码验证5.4.2 循环依赖概念及解决方案5.4.3 三级缓存的设计原理 5.5 循环依赖源码流程剖析5.6 Aware接口 六、IoC容器实例化Bean完整流程图展示七、Spring xml方式整和第三方框架7.1 Mybatis整合Spring实现7.2、MyBatis整合Spring源码解析7.3 加载外部properties文件7.4、自定义空间步骤 一、Spring配置非定义Bean
以上在xml中配置的Bean都是自己定义的例如: UserDaolmplUserServicelmpl。但是在实际开发中有些功能类并不是我们自己定义的而是使用的第三方jar包中的那么这些Bean要想让Spring进行管理也需要对其进行配置
配置非自定义的Bean需要考虑如下两个问题 被配置的Bean的实例化方式是什么无参构造、有参构造、静态工厂方式还是实例化工厂方式被配置的Bean是否需要注入必要属性
1.1 DruidDataSource
配置Druid数据源交由Spring管理 导入Druid坐标
!--mysql驱动--
dependencygroupIdmysql/groupidartifactIdmysql-connector-java/artifactIdversion5.1.49/version
/dependency
!-- druid数据源--
dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.23/version
/dependency 配置文件xml
bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName valuecom.mysql.cj.jdbc.Driver/propertyproperty nameurl valuejdbc:mysql://localhost:3306/mybatis/propertyproperty nameusername valueroot/propertyproperty namepassword value123456/property
/bean 1.2、Connection
Connection的产生是通过DriverManager的静态方法getConnection获取的所以我们要用静态工厂方式配置
bean classjava.lang.class factory-methodforNameconstructor-arg nameclassName valuecom.mysql.jdbc.Driver /
/bean
bean idconnection classjava.sql.DriverManager factory-methodgetConnection scopeprototypeconstructor-arg nameurl valuejdbc:mysql:///mybatis /constructor-arg nameuser valueroot/constructor-arg namepassword value123456/
/bean 1.3、Date
产生一个指定日期格式的对象原始代码如下
String currentTimeStr 2023-08-27 07:20:00 ;
SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);
Date date simpleDateFormat.parse(currentTimeStr);可以看成是实例工厂方式使用Spring配置方式产生Date实例
bean idsimpleDateFormat classjava.text.SimpleDateFormatconstructor-arg namepattern valueyyyy-MM-dd HH:mm:ss /
/bean
bean iddate factory-beansimpleDateFormat factory-methodparseconstructor-arg namesource value2023-08-27 07:20:00/
/bean 1.4、SqlSessionFactory
配置SqlSessionFactory交由Spring管理 导入Mybatis相关坐标
dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.10/version
/dependency
dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.30/version
/dependency!--静态工厂方法--
bean idinputStream classorg.apache.ibatis.io.Resources factory-methodgetResourceAsStreamconstructor-arg nameresource valuemybatis-config.xml/constructor-arg
/bean
!--无参构造实例化--
bean idbuilder classorg.apache.ibatis.session.SqlSessionFactoryBuilder/bean
!--实例化工厂--
bean idfactory factory-beanbuilder factory-methodbuildconstructor-arg nameinputStream refinputStream/constructor-arg
/bean 二、Bean实例化的基本流程
2.1 BeanDefinition
Spring容器在进行初始化的时候会将xml配置的bean信息封装成一个BeanDefinition对象所有的BeanDefinition对象会集中存储在BeanDefinitionMap集合当中Spring框架会调用读取器读取BeanDdfinitionMap当中的每一个信息通过反射创建出bean对象然后再进行初始化操作最后将所有的数据全部存储到singletonObjects集合当中最后通过getBean方法在singletonObjects集合当中找到创建的Bean对象 DefaultListableBeanFactory对象内部维护着一个Map用于存储封装好的BeanDefinitionMap
public class DefaultListableBeanFactory extends ... implements ... {//存储bean标签对应的BeanDefinition对象//key:是Bean的beanName,value:是Bean定义对象BeanDefinitionprivate final MapString,BeanDefinition beanDefinitionMap;
}Spring框架会取出beanDefinitionMap中的每个BeanDefinition信息反射构造方法或调用指定的工厂方法生成Bean实例对象所以只要将BeanDefinition注册到beanDefinitionMap这个Map中,Spring就会进行对应的Bean的实例化操作
2.2 单例池和流程总结
基本流程
加载xml配置文件解析获取配置中的每个bean的信息封装成一个个的BeanDefinition对象;将BeanDefinition存储在一个名为beanDefinitionMap的MapString,BeanDefinition中;ApplicationContext底层遍历beanDefinitionMap创建Bean实例对象;创建好的Bean实例对象被存储到一个名为singletonObjects的MapString,Object中;当执行applicationContext.getBean(beanName)时从singletonObjects去匹配Bean实例返回。 三、Spring的bean工厂后处理器
3.1 bean工厂后处理器入门
Spring的后处理器是Spring对外开发的重要扩展点允许我们介入到Bean的整个实例化流程中来以达到动态注册BeanDefinition动态修改BeanDefinition以及动态修改Bean的作用。
Spring主要有两种后处理器: BeanFactoryPostProcessor: Bean工厂后处理器在BeanDefinitionMap填充完毕Bean实例化之前执行;BeanPostProcessor: Bean后处理器一般在Bean实例化之后填充到单例池singletonObjects之前执行。
Bean工厂后处理器-BeanFactoryPostProcessor BeanFactoryPostProcessor是一个接口规范实现了该接口的类只要交由Spring容器管理的话那么Spring就会回调该接口的方法用于对BeanDefinition注册和修改的功能。
BeanFactoryPostProcessor定义如下
public interface BeanFactoryPostProcessor {void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
} 3.2、注册BeanDefinition
使用这种方法可以不用再spring容器内在创建一个类的bean标签
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println(beandefinitionMap填充完毕后回调该方法);//1.注册一个beandefinition 创建一个RootBeanDefinition()对象RootBeanDefinition rootBeanDefinition new RootBeanDefinition();rootBeanDefinition.setBeanClassName(com.huanglei.Dao.Impl.processorImpl);//2.将beanFactory强转成DefaultListableBeanFactory类型DefaultListableBeanFactory beanFactory1 (DefaultListableBeanFactory) beanFactory;beanFactory1.registerBeanDefinition(processor,rootBeanDefinition);}
} Test
public void demo2(){ClassPathXmlApplicationContext classPathXmlApplicationContext new ClassPathXmlApplicationContext(beans.xml);Object processor classPathXmlApplicationContext.getBean(processor);System.out.println(processor);
} 3.3、BeanDefinitionRegistryPostProcessor
Spring提供了一个BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor专门用于注册BeanDefinition操作
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {//创建一个RootBeanDefinition()对象RootBeanDefinition rootBeanDefinition new RootBeanDefinition();rootBeanDefinition.setBeanClassName(com.huanglei.Dao.Impl.processorImpl);//不需要强转就可以创建一个BeanbeanDefinitionRegistry.registerBeanDefinition(personDao,rootBeanDefinition);}Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
} 3.4 完善实例化流程图
BeanFactoryPostProcessor在SpringBean的实例化过程中的体现 3.5、自定义Component
要求
自定义MyComponent注解使用在类上;使用资料中提供好的包扫描器工具BaseClassScanUtils完成指定包的类扫描;自定义BeanFactoryPostProcessor完成注解MyComponent的解析解析后最终被Spring管理。
BaseClassScanUtils:
public class BaseClassScanUtils {//设置资源规则private static final String RESOURCE_PATTERN /**/*.class;public static MapString, Class scanMyComponentAnnotation(String basePackage) {//创建容器存储使用了指定注解的Bean字节码对象MapString, Class annotationClassMap new HashMapString, Class();//spring工具类可以获取指定路径下的全部类ResourcePatternResolver resourcePatternResolver new PathMatchingResourcePatternResolver();try {String pattern ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX ClassUtils.convertClassNameToResourcePath(basePackage) RESOURCE_PATTERN;Resource[] resources resourcePatternResolver.getResources(pattern);//MetadataReader 的工厂类MetadataReaderFactory refractory new CachingMetadataReaderFactory(resourcePatternResolver);for (Resource resource : resources) {//用于读取类信息MetadataReader reader refractory.getMetadataReader(resource);//扫描到的classString classname reader.getClassMetadata().getClassName();Class? clazz Class.forName(classname);//判断是否属于指定的注解类型if(clazz.isAnnotationPresent(MyComponent.class)){//获得注解对象MyComponent annotation clazz.getAnnotation(MyComponent.class);//获得属value属性值String beanName annotation.value();//判断是否为if(beanName!null!beanName.equals()){//存储到Map中去annotationClassMap.put(beanName,clazz);continue;}//如果没有为,那就把当前类的类名作为beanNameannotationClassMap.put(clazz.getSimpleName(),clazz);}}} catch (Exception exception) {}return annotationClassMap;}public static void main(String[] args) {MapString, Class stringClassMap scanMyComponentAnnotation(com.huanglei);System.out.println(stringClassMap);}
} Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
public interface MyComponent {String value();
} MyComponent(One)
public class OneBean {
} 四、Spring的Bean后处理器
4.1 概念和入门
Bean被实例化过后在最后缓存到singletonObjects单例池之前中间会进行Bean的初始化操作例如属性的赋值初始化操作init-method其中包含着一个点BeanPostProcessor这里被称为Bean后处理器。如果实现了这个接口那么就会被Spring管理然后Spring会自动调用
public class MyBeanPostProcesser implements BeanPostProcessor {Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(beanNamepostProcessBeforeInitialization);return null;}Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println(beanNamepostProcessAfterInitialization);return null;}
}postProcessBeforeInitialization方法和postProcessAfterInitialization方法需要进行手动创建接口中实现的是null返回值的方法两者方法在bena创建之后执行,加入到singletonObjects之前执行
4.2 当中的一些调用方法的顺序
先执行bean的构造方法执行before方法执行InitializingBean接口中的afterPropertiesSet()方法执行在xml文件中设置的Bean的init-method方法执行after方法
执行操作如下
4.3 更加详细的实例化基本操作
BeanPostProcessor在 SpringBean的实例化过程中的体现
五、Spring的生命周期
5.1 概述
Spring Bean的生命周期是从Bean 实例化之后即通过反射创建出对象之后导Bean成为一个完整对象最终储存到单例池中这个过程被称为SpringBean的生命周期。
Spring Bean的生命周期大体上分为三个阶段: Bean的实例化阶段: Spring框架会取出BeanDefinition的信息进行判断当前Bean的范围是否是singleton的,是否不是延迟加载的是否不是FactoryBean等最终将一个普通的singleton的Bean通过反射进行实例化Bean的初始化阶段∶Beane创建之后还仅仅是个”半成品“还需要对Bean实例的属性进行填充、执行一些Aware接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化init方法等。该阶段是Spring最具技术含量和复杂度的阶段Aop增强功能后面要学习的Spring的注解功能等、spring高频面试题Bean的循环引用问题都是在这个阶段体现的Bean的完成阶段:经过初始化阶段Bean就成为了一个完整的Spring Bean被存储到单例池singletonObjects中去了即完成了Spring Bean的整个生命周期。
5.2 初始化阶段执行的步骤
由于Bean的初始化阶段的步骤比较复杂所以着重研究Bean的初始化阶段 Spring Bean的初始化过程涉及如下几个过程:
Bean实例的属性填充Aware接口属性注入BeanPostProcessor的before()方法回调lnitializingBean接口的初始化方法回调自定义初始化方法init回调BeanPostProcessor的after()方法回调
5.3 初始化阶段注入属性信息封装
BeanDefinition 中有对当前Bean实体的注入信息通过属性propertyValues进行了存储
bean iduserDao classcom.huanglei.Dao.Impl.UserDaoImpl/beanbean iduserService classcom.huanglei.service.Impl.UserServiceImplproperty namedao refuserDao/propertyproperty nameusername valueAAA/property
/bean 5.4、属性注入的三种情况
Spring在进行属性注入时会分为如下几种情况:
注入普通属性String、int或存储基本类型的集合时直接通过set方法的反射设置进去;注入单向对象引用属性时从容器中getBean获取后通过set方法反射设置进去如果容器中没有则先创建被注入对象Bean实例完成整个生命周期后在进行注入操作注入双向对象引用属性时就比较复杂了涉及了循环引用循环依赖问题下面会详细阐述解决方案。
5.4.1 单项注入的代码验证
public class UserServiceImpl implements UserService{private UserDao dao;private String username;public UserServiceImpl() {System.out.println(实例化UserService);}public UserServiceImpl(UserDao dao, String username) {this.dao dao;this.username username;}public void setDao(UserDao dao) {System.out.println(执行setDao方法);this.dao dao;}public void setUsername(String username) {this.username username;}
} public class UserDaoImpl implements UserDao{public UserDaoImpl() {System.out.println(实例化UserDao);}
} userDao在userService前面
bean iduserDao classcom.huanglei.Dao.Impl.UserDaoImpl/beanbean iduserService classcom.huanglei.service.Impl.UserServiceImplproperty namedao refuserDao/propertyproperty nameusername valueAAA/property
/bean 执行顺序
实例化UserDao实例化UserService执行setDao方法
userDao在userService后面
bean iduserService classcom.huanglei.service.Impl.UserServiceImplproperty namedao refuserDao/propertyproperty nameusername valueAAA/property
/beanbean iduserDao classcom.huanglei.Dao.Impl.UserDaoImpl/bean
总结 就是说明如果包含了我要调用的Bean对象有就调用若无就先创建Bean对象 5.4.2 循环依赖概念及解决方案
多个实体之间相互依赖并形成闭环的情况就叫做 “循环依赖”也叫做 “循环引用” bean iduserService classcom.huanglei.service.Impl.UserServiceImplproperty namedao refuserDao/property
/beanbean iduserDao classcom.huanglei.Dao.Impl.UserDaoImplproperty nameservice refuserService/property
/bean public class UserDaoImpl implements UserDao{private UserService service; public void setService(UserService service){this.service service;}
}
public class UserServiceImpl implements UserService{private UserDao dao;public void setDao(UserDao dao) {this.dao dao;}
} 可以利用三级缓存来
5.4.3 三级缓存的设计原理
Spring提供了三级缓存存储完整Bean实例和半成品Bean实例用于解决循环引用问题 在DefaultListableBeanFactory的上四级父类DefaultSingletonBeanRegistry中提供如下三个Map:
public class DefaultsingletonBeanRegistry ... {//1、最终存储单例Bean成品的容器即实例化和初始化都完成的Bean称之为一级缓存MapString,Object singletonObjects new ConcurrentHashMap(256);//2、早期Bean单例池缓存半成品对象且当前对象已经被其他对象引用了称之为二级缓存MapString,Object earlySingletonObjects new ConcurrentHashMap(16);//3、单例Bean的工厂池缓存半成品对象对象未被引用使用时在通过工厂创建Bean称之为三级缓存MapString,ObjectFactory? singletonFactories new HashMap(16);
}5.5 循环依赖源码流程剖析
UserService和UserDao循环依赖的过程结合上述三级缓存描述一下
UserService 实例化对象但尚未初始化将UserService存储到三级缓存;UserService 属性注入需要UserDao从缓存中获取没有UserDao;UserDao 实例化对象但尚未初始化将UserDao存储到到三级缓存;UserDao 属性注入需要UserService从三级缓存获取UserServiceUserService从三级缓存移入二级缓存;UserDao执行其他生命周期过程最终成为一个完成Bean存储到一级缓存删除二三级缓存;UserService注入UserDao;UserService执行其他生命周期过程最终成为一个完成Bean存储到一级缓存删除二三级缓存。
5.6 Aware接口
Aware接口是一种框架辅助属性注入的一种思想其他框架中也可以看到类似的接口。框架具备高度封装性我们接触到的一般都是业务代码一个底层功能API不能轻易的获取到但是这不意味着永远用不到这些对象如果用到了就可以使用框架提供的类似Aware的接口让框架给我们注入该对象。
Aware接口回调方法作用ServletContextAwaresetServletContext(ServletContext context)Spring框架回调方法注入ServletContext对象,web环境下才生效BeanFactoryAwaresetBeanFactory(BeanFactory factory)Spring框架回调方法注入beanFactory对象BeanNameAwaresetBeanName(String beanName)Spring框架回调方法注入当前Bean在容器中的beanNameApplicationContextAwaresetApplicationContext(ApplicationContext applicationContext)Spring框架回调方法注入applicationContext对象
六、IoC容器实例化Bean完整流程图展示 七、Spring xml方式整和第三方框架
xml整合第三方框架有两种整合方案 不需要自定义名空间不需要使用Spring的配置文件配置第三方框架本身内容例如: MyBatis;需要引入第三方框架命名空间需要使用Spring的配置文件配置第三方框架本身内容例如:Dubbo。
7.1 Mybatis整合Spring实现
Spring整合MyBatis之前已经在Spring中简单的配置了SqlSessionFactory但是这不是正规的整合方式,MyBatis提供了mybatis-spring.jar专门用于两大框架的整合。 Spring整合MyBatis的步骤如下:
导入MyBatis整合Spring的相关坐标;
dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactId!--注意版本因为版本过低的原因在这里卡了很久--version3.0.1/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.2.25.RELEASE/version
/dependency 编写Mapper和Mapper.xml;配置SqlSessionFactoryBean和MapperScannerConfigurer;
bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName valuecom.mysql.cj.jdbc.Driver/propertyproperty nameurl valuejdbc:mysql://localhost:3306/itheima/propertyproperty nameusername valueroot/propertyproperty namepassword value123456/property
/bean
!--配置SqlSessionFactoryBean作用将SqlSessionFactory存储到spring容器--
bean classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/property
/bean
!--MapperScannerConfigurer作用扫描指定的包产生Mapper对象存储到Spring容器--
bean classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valuecom.huanglei.mapper/property
/beanbean iduserService classcom.huanglei.service.Impl.UserServiceImplproperty namecarMapper refcarMapper/property
/bean 编写测试代码
7.2、MyBatis整合Spring源码解析
整合包里提供了一个SqlSessionFactoryBean和一个扫描Mapper的配置对象SqlSessionFactoryBean一旦被实例化就开始扫描Mapper并通过动态代理产生Mapper的实现类存储到Spring容器中。相关的有如下四个类:
sqlSessionFactoryBean:需要进行配置用于提供SqlSessionFactory;MapperScannerConfigurer:需要进行配置用于扫描指定mapper注册BeanDefinition;MapperFactoryBean: Mapper的FactoryBean获得指定Mapper时调用getObject方法;ClassPathMapperScanner: definition.setAutowireMode(2)修改了自动注入状态所以MapperFactoryBean中的setSqlSessionFactory会自动注入进去。
7.3 加载外部properties文件
Spring整合其他组件时就不像MyBatis这么简单了例如Dubbo框架在于Spring进行整合时要使用Dubbo提供的命名空间的扩展方式自定义了一些Dubbo的标签
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:dubbohttp://dubbo.apache.org/schema/dubboxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbohttp://dubbo.apache.org/schema/dubbo/dubbo.xsd!-- 配置Dubbo应用信息 --dubbo:application nameyour-application-name /!-- 配置注册中心 --dubbo:registry addresszookeeper://127.0.0.1:2181 /!-- 配置服务提供者 --dubbo:protocol namedubbo port20880 /dubbo:service interfacecom.example.YourServiceInterface refyourServiceBean /!-- 配置其他Bean --!-- 消费者配置 --dubbo:consumer checkfalse timeout1000 retries0/
/beans 通过配置context文件来加载外部properties文件
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd!--通过context加载properties文件--context:property-placeholder locationclasspath:jdbc.properties/bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty namedriverClassName value${jdbc.driver}/propertyproperty nameurl value${jdbc.url}/propertyproperty nameusername value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!--配置SqlSessionFactoryBean作用将SqlSessionFactory存储到spring容器--bean classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/property/bean!--MapperScannerConfigurer作用扫描指定的包产生Mapper对象存储到Spring容器--bean classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valuecom.huanglei.mapper/property/beanbean iduserService classcom.huamglei.service.Impl.UserServiceImplproperty namecarMapper refcarMapper/property/bean
/beans 7.4、自定义空间步骤
将自定义标签的约束与物理约束文件与网络约束名称的约束以键值对形式存储到一个spring.schemas文件里该文件存储在类加载路径的META-INF里Spring会自动加载到;将自定义命名空间的名称与自定义命名空间的处理器映射关系以键值对形式存在到一个叫spring.handlers文件里该文件存储在类加载路径的 META-INF里Spring会自动加载到;准备好NamespaceHandler如果命名空间只有一个标签那么直接在parse方法中进行解析即可一般解析结果就是注册该标签对应的BeanDefinition。如果命名空间里有多个标签那么可以在init方法中为每个标签都注册一个BeanDefinitionParser在执行NamespaceHandler的parse方法时在分流给不同的 BeanDefinitionParser进行解析(重写doParse方法即可)。