上一篇有讲解析xml,其中有说道BeanDefinition,但是不够详细。AbstractBeanDefinition是spring配置文件bean标签的实现,了解这个类很关键。源代码如下:
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { /** * Constant for the default scope name: "", equivalent to singleton status * but to be overridden from a parent bean definition (if applicable). */ public static final String SCOPE_DEFAULT = ""; /** * Constant that indicates no autowiring at all. * @see #setAutowireMode */ public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; /** * Constant that indicates autowiring bean properties by name. * @see #setAutowireMode */ public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; /** * Constant that indicates autowiring bean properties by type. * @see #setAutowireMode */ public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; /** * Constant that indicates autowiring a constructor. * @see #setAutowireMode */ public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; /** * Constant that indicates determining an appropriate autowire strategy * through introspection of the bean class. * @see #setAutowireMode * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies, * use annotation-based autowiring for clearer demarcation of autowiring needs. */ @Deprecated public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; /** * Constant that indicates no dependency check at all. * @see #setDependencyCheck */ public static final int DEPENDENCY_CHECK_NONE = 0; /** * Constant that indicates dependency checking for object references. * @see #setDependencyCheck */ public static final int DEPENDENCY_CHECK_OBJECTS = 1; /** * Constant that indicates dependency checking for "simple" properties. * @see #setDependencyCheck * @see org.springframework.beans.BeanUtils#isSimpleProperty */ public static final int DEPENDENCY_CHECK_SIMPLE = 2; /** * Constant that indicates dependency checking for all properties * (object references as well as "simple" properties). * @see #setDependencyCheck */ public static final int DEPENDENCY_CHECK_ALL = 3; 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 boolean autowireCandidate = true; private boolean primary = false; private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<String, AutowireCandidateQualifier>(0); private boolean nonPublicAccessAllowed = true; private boolean lenientConstructorResolution = true; private ConstructorArgumentValues constructorArgumentValues; private MutablePropertyValues propertyValues; private MethodOverrides methodOverrides = new MethodOverrides(); private String factoryBeanName; private String factoryMethodName; private String initMethodName; private String destroyMethodName; private boolean enforceInitMethod = true; private boolean enforceDestroyMethod = true; private boolean synthetic = false; private int role = BeanDefinition.ROLE_APPLICATION; private String description; private Resource resource; 。。。。。。。。。 }
可以看到上面很多是不是都很面熟。其中的singleton,prototype等这些。这些其实就是配置文件中bean可以有的属性,但是singleton和prototype只是对应scope而已,并且其中很多是有默认值的,像autowireMode默认为不自动装配,lazyinit为false。还有一个synthetic,意思为合成,用户配置的都是bean默认都为false。但是spring启动的时候会自己创建一些bean加入到容器中(会在AOP讲解中详细说明),如果是spring的一般会设置为true了。BeanDefinition中两个重要的属性为ConstructorArgumentValues和MutablePropertyValues。其中我们知道spring有通过默认的构造函数创建bean,用户也可以指定构造器来实例化bean。这里的ConstructorArgumentValues就是构造函数事用到的。这里参照下面的测试类代码说明:
public class Model1 { private int age; private String sex; private String name; public void init(){ System.out.println("init"); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Model1(){ } public Model1(int age, String sex, String name) { super(); this.age = age; this.sex = sex; this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Model1 [age=" + age + ", sex=" + sex + ", name=" + name + "]"; } } @Test public void testSpringBeanDefinitionConstructorArgumentValues(){ AbstractBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(Model1.class); beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new ConstructorArgumentValues.ValueHolder(21)); beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new ConstructorArgumentValues.ValueHolder("female")); beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new ConstructorArgumentValues.ValueHolder("C++")); RootBeanDefinition mbd = new RootBeanDefinition(beanDefinition); mbd.setScope("prototype"); mbd.setInitMethodName("init"); BeanDefinitionRegistry reg=new DefaultListableBeanFactory(); reg.registerBeanDefinition("model", mbd); BeanFactory factory=(BeanFactory)reg; Model1 model1=(Model1)factory.getBean("model"); Model1 model2=(Model1)factory.getBean("model"); System.out.println(model1.getAge()); Assert.assertEquals(false, model1==model2); }
读取配置文件xml的时候会创建 GenericBeanDefinition类,它继承了AbstractBeanDefinition。而beanDefinition.getConstructorArgumentValues().addGenericArgumentValue就是向构造函数的参数设置。当然这里也可以指定参数的索引位置的方法addIndexedArgumentValue,索引是从0开始。如果没有指定,那就是按代码的执行前后顺序和类型来判断。
MutablePropertyValues则是实例化属性时用到,测试代码如下:
@Test public void testSpringBeanDefinitionMutablePropertyValues(){ AbstractBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(Model1.class); MutablePropertyValues properties=new MutablePropertyValues(); //设置属性的值 properties.add("age", 21); properties.add("sex", "male"); properties.add("name", "java bean"); beanDefinition.setPropertyValues(properties); RootBeanDefinition mbd = new RootBeanDefinition(beanDefinition); mbd.setScope("singleton"); mbd.setInitMethodName("init"); BeanDefinitionRegistry reg=new DefaultListableBeanFactory(); //向IOC容器注册Bean reg.registerBeanDefinition("model", mbd); BeanFactory factory=(BeanFactory)reg; Model1 model1=(Model1)factory.getBean("model"); Model1 model2=(Model1)factory.getBean("model"); System.out.println(model1.getAge()); Assert.assertEquals(false, model1==model2); }
如果是用这种方式,那bean一定要有默认的无参构造函数,并且是标准的javabean类。即set方法要正确,否则要报错。
相关推荐
spring4.0源码,需要的可以下载,还是很完整的.
spring4.0.x源码
Spring 4.0.x版本的源代码。
利用maven构建的spring4.0框架的demo
spring4.0完整jar包 包含spring4.0 所有的jar包文件 打包下载
spring4.0框架所需的jar包,没有包含maven,没有其他框架用的jar包,仅仅是spring框架,每一个都是自己下载的,搭建成功。
Spring4.0-API CHM格式,很难得的,希望能帮到大家!
spring-framework也就是Spring4.0官方jar包,Spring框架,由Rod Johnson开发,是一个非常强大的反转控制(IOC)框架,以帮助分离项目组件之间的依赖关系
spring4.0详细教程,简单明了,一看即懂 ,适合初学者
Spring4.0+Hibernate4.0+Struts2.3整合案例:实现增删改查。 ===================== application.xml: xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=...
Spring框架4.0这个版本支持了众多Java 8的新特性,新增了对WebSocket、STOMP等技术的支持,并增强了测试、Web开发的便利性,另外,在这个版本中还删除了废弃的方法和类。
spring4.0+spring MVC4.0+hibernate4.3框架整合测试案例,支持事务,全注解,配置清晰,基础BaseDao接口实现都已写好,MVC分层,含所有需要的jar包,数据库文件。
Spring4.0+SpringMVC4.0+Mybatis3.2框架整合例子(SSM) 自动生成代码 简单试用
Spring4.0源代码,GitHub 2014.1月份最新版
Spring4.0的jar包,官方源码,javadoc
spring 4.0.x eclipse编译 可导入
spring 4.0企业开发实战。写的不错,。。。。。。。。。