这篇文章主要讲解了“Spring实现解析默认标签的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring实现解析默认标签的方法”吧!
parseDefaultElement(ele, delegate);
void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//解析import标签
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
//解析alias标签
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
//解析bean标签
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
//解析beans标签,递归处理
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
doRegisterBeanDefinitions(ele);
}
}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//1.委托BeanDefinitionPaserDelegate类进行元素解析,将BeanDefinition封装进BeanDefinitionHolder里面
//包含class、name、id属性
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//2.若默认标签的子节点下有自定义属性,还需要再对自定义标签解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
//3.委托BeanDefinitionReaderUtils注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
//4.发出响应事件,通知想关心的监听事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinition是一个接口,其抽象实现类为AbstractBeanDefinition,有三个子类,分别为RootBeanDefinition、ChildBeanDefinition
和GenericBeanDefinition. BeanDefinition是配置文件bean元素在容器中的内部表现形式,和bean中属性一一对应.Spring通过
BeanDefinition将配置文件中的bean配置信息转换为容器的内部表示,并将这些信息注册到BeanDefinitionRegistry中,它就是Spring
配置信息的内存数据库,是一个Map,后续操作直接从该BeanDefinitionRegistry中读取配置信息.
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
//解析id属性
String id = ele.getAttribute(ID_ATTRIBUTE);
//解析name属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//若nameAttr不为空,解析别名属性
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
//若没有指定id属性,使用别名的第一个代替
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//进一步解析其他所有属性并封装到beanDefinition中
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName =
BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
String className = null;
//解析className属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
//解析parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
//创建用于承载属性的GenericBeanDefinition,直接new的,并set传进去的参数
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//1.硬编码解析bean的各种属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//2.解析description
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//3.解析元数据
parseMetaElements(ele, bd);
//4.解析lookup-method属性,见附录1,实际要返回的bean是在配置文件里面配置的
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//5.解析replace-method属性,不但可以动态地替换返回实体的bean,而且还能动态地更改原有方法的逻辑
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//6.解析构造函数参数,property元素和qualifier元素
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
}
步骤1:硬编码解析bean的各种属性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String
beanName,BeanDefinition containingBean, AbstractBeanDefinition bd) {
//解析scope属性
if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error("Specify either 'scope' or 'singleton', not both", ele);
}
}
//解析singleton属性
else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?
BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
}
else if (containingBean != null) {
bd.setScope(containingBean.getScope());
}
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
//解析lazy-init属性,若不设置或者设置成其他字符都会设置为false
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
//解析autowire属性
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
//解析init-method属性
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
if (!"".equals(initMethodName)) {
bd.setInitMethodName(initMethodName);
}
}
else {
if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
}
//解析destroy-method属性
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
if (!"".equals(destroyMethodName)) {
bd.setDestroyMethodName(destroyMethodName);
}
}
else {
if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
}
//解析factory-method属性
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
//解析factory-bean属性
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
步骤4、5:见附录1、2 步骤6:解析构造函数参数
上述解析后的数据都放在AbstractBeanDefinition中.
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean singleton = true;
private boolean prototype = false;
private boolean abstractFlag = false;
private boolean lazyInit = false;
private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private String[] dependsOn;
//构造函数属性
private ConstructorArgumentValues constructorArgumentValues;
//普通属性集合
private MutablePropertyValues propertyValues;
//方法重写的持有者,记录lookup-method、replace-method元素
private MethodOverrides methodOverrides = new MethodOverrides();
private String factoryBeanName;
private String factoryMethodName;
private String initMethodName;
private String destroyMethodName;
//是否执行init-method和destroy-method
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析BeanDefinition
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
//注册BeanDefinition到registry
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
//通知监听器解析及完成注册,当程序开发人员需要对注册BeanDefinition事件进行监听时可以通过注册监听器的方
//式并将处理逻辑写入监听器中,目前Spring中没有对此事件做任何逻辑处理
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry){
String beanName = definitionHolder.getBeanName();
//使用beanName做唯一标识注册
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String aliase : aliases) {
//使用别名做注册
registry.registerAlias(beanName, aliase);
}
}
}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
//做校验,抛异常部分已删除
((AbstractBeanDefinition) beanDefinition).validate();
}
}
//beanDefinitionMap就是存放注册信息的全局变量,会存在并发访问的情况,加锁,它是ConcurrentHashMap
//Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);
synchronized (this.beanDefinitionMap) {
Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
//处理已经注册beanName的情况
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding) {
//此处代码简略了,不允许覆盖则抛异常,允许覆盖则记录下日志
}
}
else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
//真正进行注册
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//清除缓存
resetBeanDefinition(beanName);
}
protected void processAliasRegistration(Element ele) {
//获取beanName
String name = ele.getAttribute(NAME_ATTRIBUTE);
//获取别名alias
String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
boolean valid = true;
//之前有一些校验,删掉了
if (valid) {
try {
//注册
getReaderContext().getRegistry().registerAlias(name, alias);
}
getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
}
}
protected void importBeanDefinitionResource(Element ele) {
//解析resource属性,形如<import resource=”***.xml”/>
String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
//不存在直接返回
if (!StringUtils.hasText(location)) {
getReaderContext().error("Resource location must not be empty", ele);
return;
}
location = environment.resolveRequiredPlaceholders(location);
Set<Resource> actualResources = new LinkedHashSet<Resource>(4);
//判断是相对路径还是绝对路径
boolean absoluteLocation = false;
try {
absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
}
if (absoluteLocation) {
try {
//是绝对路径,直接调用loadBeanDefinitions加载BeanDefinition,递归操作
int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
}
}else {
try {
int importCount;
//计算出绝对路径,进行loadBeanDefinitons
Resource relativeResource = getReaderContext().getResource().createRelative(location);
if (relativeResource.exists()) {
importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
actualResources.add(relativeResource);
}
else {
String baseLocation = getReaderContext().getResource().getURL().toString();
importCount = getReaderContext().getReader().loadBeanDefinitions(
StringUtils.applyRelativePath(baseLocation, location), actualResources);
}
}
}
Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}
附录1:解析lookup-method
public class User {
public void showMe(){
System.out.println("I am a User");
}
}
public class Teacher extends User{
@Override
public void showMe() {
System.out.println("I am a teacher");
}
}
public abstract class GetBeanTest {
public void showMe(){
this.getBean().showMe();
}
public abstract User getBean();
}
<bean id="getBeanTest" class="com.lwh.spring.look.GetBeanTest">
<lookup-method name="getBean" bean="teacher"/>
</bean>
<bean id="teacher" class="com.lwh.spring.look.Teacher"/>
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)){
Element ele = (Element) node;
//获取要修饰的方法
String methodName = ele.getAttribute(NAME_ATTRIBUTE);
//获取配置返回的bean
String beanRef = ele.getAttribute(BEAN_ELEMENT);
LookupOverride override = new LookupOverride(methodName, beanRef);
override.setSource(extractSource(ele));
overrides.addOverride(override);
}
}
}
附录2:解析replace-method
public class TestChangeMethod {
public void changeMe(){
System.out.println("changeMe");
}
}
public class TestMethodReplacer implements MethodReplacer{
public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
System.out.println("我替换了原有的方法");
return null;
}
}
<bean id="testChangeMethod" class="com.lwh.spring.replace.TestChangeMethod">
<replaced-method name="changeMe" replacer="replacer"/>
</bean>
<bean id="replacer" class="com.lwh.spring.replace.TestMethodReplacer"/>
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
//仅当在Spring默认bean的子元素下且为replace-method时才有效
if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
Element replacedMethodEle = (Element) node;
//提取要替换的旧的方法,changeMe
String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
//提取对应的新的替换方法,replacer
String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
// Look for arg-type match elements.
List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
for (Element argTypeEle : argTypeEles) {
//记录参数
String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
if (StringUtils.hasText(match)) {
replaceOverride.addTypeIdentifier(match);
}
}
replaceOverride.setSource(extractSource(replacedMethodEle));
overrides.addOverride(replaceOverride);
}
}
}
感谢各位的阅读,以上就是“Spring实现解析默认标签的方法”的内容了,经过本文的学习后,相信大家对Spring实现解析默认标签的方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/liwanghong/blog/3114992