您的位置:首页 > 编程语言 > Java开发

Spring 源码阅读-BeanFactory

2016-08-10 00:00 525 查看
#Spring 源码阅读(一)

##一.环境准备
IDEA+Maven+Jetty。

pom.xml代码

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>Test2</groupId>
<artifactId>Test2</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Test2 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.6.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>

<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
</dependencies>
<!--Jetty插件-->
<build>
<finalName>Test2</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.6.10.v20130312</version>
<configuration>
<webAppSourceDirectory>${basedir}/webapp</webAppSourceDirectory>
<stopKey>stop</stopKey>
<stopPort>5580</stopPort>

<scanIntervalSeconds>0</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
<systemProperties>
<systemProperty>
<name>global.config.path</name>
<value>${basedir}/src/main/resources/config</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</project>

##二.测试代码

Bean类

package com.wm;

public class People implements Serializable {

Integer age;
String sex;
String name;
public String getName() {   return name;}
public void setName(String name) {this.name = name;}
public Integer getAge() {return age;}
public void setAge(Integer age) {this.age = age;}
public String getSex() {return sex;}
public void setSex(String sex) {this.sex = sex;}
@Override
public String toString(){
StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append("People name:")
.append(name)
.append(" sex:")
.append(sex)
.append(" age:")
.append(age);
return stringBuffer.toString();
}
}

Client类

public class Client {

public  static void main(String[] args){

ClassPathResource classPathResource=new ClassPathResource("/spring/spring-mvc.xml");
BeanFactory beanFactory=new XmlBeanFactory(classPathResource);
People people=(People) beanFactory.getBean("people");
people.setAge(12);
people.setName("Lily");
people.setSex("girl");
System.out.println(people.toString());
}
}

Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 
//加上这一行
<bean id="people" class="com.wm.People"></bean>

</beans>

输出结果:
People name:Lily sex:girl age:12
##三.分析
###3.1 首先根据配置文件名称获取ClassPathResource。

1.ClassPathResource代码

public ClassPathResource(String path) {
//类加载设置为空
this(path, (ClassLoader)null);
}

public ClassPathResource(String path, ClassLoader classLoader) {
Assert.notNull(path, "Path must not be null");
//文件路径
String pathToUse = StringUtils.cleanPath(path);
if(pathToUse.startsWith("/")) {
pathToUse = pathToUse.substring(1);
}
this.path = pathToUse;
//如果类加载器为空获取默认类加载器
this.classLoader = classLoader != null?classLoader:ClassUtils.getDefaultClassLoader();
}

Spring实现配置文件的解析

2.Resource接口
Resource其实就是封装Java的URL

public interface Resource extends InputStreamSource {
//文件是否存在
boolean exists();
//文件是否可讀
boolean isReadable();
//文件能否打開
boolean isOpen();

URL getURL() throws IOException;

URI getURI() throws IOException;

File getFile() throws IOException;

long contentLength() throws IOException;

long lastModified() throws IOException;

Resource createRelative(String var1) throws IOException;

String getFilename();

String getDescription();
}

对应不同资源来源有不同的Resource实现类

3.ByteArrayResource 字节数组资源

//将不可变字节数组转换为字符串
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.byteArray);
}

4.ClassPathResource 类路径资源

本资源类的clazz属性存在,那么资源相对于这个clazz类相对路径的。如果不存在,那么资源类就是相对于整个应用程序的。

//路径
private final String path;
//类加载器
private ClassLoader classLoader;
//所属类
private Class<?> clazz;

public InputStream getInputStream() throws IOException {

InputStream is;
//如果所属类不为空,则调用所属类的getResourceAsStream
if(this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
} else if(this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
} else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}

if(is == null) {
throw new FileNotFoundException(this.getDescription() + " cannot be opened because it does not exist");
} else {
return is;
}
}

public URL getURL() throws IOException {
URL url = this.resolveURL();
if(url == null) {
throw new FileNotFoundException(this.getDescription() + " cannot be resolved to URL because it does not exist");
} else {
return url;
}
}

###3.2 BeanFactory beanFactory=new XmlBeanFactory(classPathResource);

1.XmlBeanFactory代码

private final XmlBeanDefinitionReader reader;
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, (BeanFactory)null);
}

public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader = new XmlBeanDefinitionReader(this);
this.reader.loadBeanDefinitions(resource);
}

2.BeanFactory 有三个子类接口:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory,还有一个实现类SimpleJndiBeanFactory。

BeanFactory代码

public interface BeanFactory {

String FACTORY_BEAN_PREFIX = "&";
//获取实例
Object getBean(String var1) throws BeansException;

<T> T getBean(String var1, Class<T> var2) throws BeansException;

<T> T getBean(Class<T> var1) throws BeansException;

Object getBean(String var1, Object... var2) throws BeansException;

<T> T getBean(Class<T> var1, Object... var2) throws BeansException;

//是否已经包含Bean
boolean containsBean(String var1);
//是否单例
boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
//是否是原型(多实例)
boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
//获取类型
Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
//获取别名
String[] getAliases(String var1);
}

3.ListableBeanFactory代码 可以列出工厂可以生产的所有实例

public interface ListableBeanFactory extends BeanFactory {
boolean containsBeanDefinition(String var1);

int getBeanDefinitionCount();
//返回工厂中所有Bean的名称
String[] getBeanDefinitionNames();
//对于给定的名字有多少份BeanDefinition
String[] getBeanNamesForType(Class<?> var1);

String[] getBeanNamesForType(Class<?> var1, boolean var2, boolean var3);

<T> Map<String, T> getBeansOfType(Class<T> var1) throws BeansException;

<T> Map<String, T> getBeansOfType(Class<T> var1, boolean var2, boolean var3) throws BeansException;

String[] getBeanNamesForAnnotation(Class<? extends Annotation> var1);
//根据注解类型,查找所有有这个注解的Bean名和Bean的Map
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> var1) throws BeansException;
//根据指定Bean名和注解类型查找指定的Bean
<A extends Annotation> A findAnnotationOnBean(String var1, Class<A> var2) throws NoSuchBeanDefinitionException;
}

4.AutowireCapableBeanFactory代码 自动装配
这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等。

public interface AutowireCapableBeanFactory extends BeanFactory {
//这个常量表明工厂没有自动装配的Bean
int AUTOWIRE_NO = 0;
//根据名称自动装配
int AUTOWIRE_BY_NAME = 1;
//根据类型自动装配
int AUTOWIRE_BY_TYPE = 2;
//根据构造方法装配
int AUTOWIRE_CONSTRUCTOR = 3;

[@Deprecated](http://my.oschina.net/jianhuaw)
int AUTOWIRE_AUTODETECT = 4;

<T> T createBean(Class<T> var1) throws BeansException;

void autowireBean(Object var1) throws BeansException;

//根据Bean名的BeanDefinition装配这个未加工的Object,执行回调和各种后处理器。
Object configureBean(Object var1, String var2) throws BeansException;

Object resolveDependency(DependencyDescriptor var1, String var2) throws BeansException;

Object createBean(Class<?> var1, int var2, boolean var3) throws BeansException;

Object autowire(Class<?> var1, int var2, boolean var3) throws BeansException;

void autowireBeanProperties(Object var1, int var2, boolean var3) throws BeansException;

void applyBeanPropertyValues(Object var1, String var2) throws BeansException;

Object initializeBean(Object var1, String var2) throws BeansException;

Object applyBeanPostProcessorsBeforeInitialization(Object var1, String var2) throws BeansException;

Object applyBeanPostProcessorsAfterInitialization(Object var1, String var2) throws BeansException;

//销毁bean
void destroyBean(Object var1);

//分解指定的依赖
Object resolveDependency(DependencyDescriptor var1, String var2, Set<String> var3, TypeConverter var4) throws BeansException;
}

5.HierarchicalBeanFactory代码 分层Bean工厂。从这个接口开始,BeanFactory有了双亲Factory,父Factory的概念。

public interface HierarchicalBeanFactory extends BeanFactory {
返回父工厂
BeanFactory getParentBeanFactory();
//查看当前工厂是否包含Bean
boolean containsLocalBean(String name);
}

直接子接口共有两个,一个是ApplicationContext,还有一个是ConfigurableBeanFactory。

总结:

1.一级接口为BeanFactory

2.三个继承他的接口,HierarchicalBeanFactory,AutowireCapableBeanFactory,ListableBeanFactory,可称为二级接口

3、ConfigurableBeanFactory可以被称为三级接口,对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry

4、ConfigurableListableBeanFactory是一个更强大的接口,继承了上述的所有接口,无所不包,称为四级接口。

(这4级接口是BeanFactory的基本接口体系。继续,下面是继承关系的2个抽象类和2个实现类:)

5、AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能。

6、AbstractAutowireCapableBeanFactory同样是抽象类,继承自AbstractBeanFactory,并额外实现了二级接口AutowireCapableBeanFactory

7、DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最强大的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口 BeanDefinitionRegistry,它并非抽象类。

8、最后是最强大的XmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更强大。提供了Xml文件相关BeanFactory的方法。可以读取xml定义的BeanDefinition文件。

BeanFactory体系图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: