1、读取bean.xml文件
2、解析bean文件,将bean信息封装到BeanDefinition对象中
加载并注册BeanDefinition流程
XmlBeanDefinitionReader:整体就是负责读取Document对象
XmlBeanDefinitionDocumentReader:整体就是负责BeanDefinition的注册工作
将BeanDefinition对象存放到BeanDefinitionRegistry 集合中
3、获取Bean实例
BeanFactory(工厂模式、接口隔离原理、抽象模板方法模式)
4、通过Bean实例查询数据库
public class TestSpringV3 {
@Test
public void test() throws Exception {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
Resource resource = new ClasspathResource("beans.xml");
InputStream inputStream = resource.getResource();
xmlBeanDefinitionReader.loadBeanDefinitions(inputStream);
UserService userService = (UserService) beanFactory. getBean("userService");
User user = new User();
user.setUsername("王五");
List<User> users = userService.queryUsers(user);
System.out.println(users);
}
}
Resource 接口
public interface Resource {
InputStream getResource();
}
ClasspathResource 类 实现Resource 接口
public class ClasspathResource implements Resource {
private String location;
public ClasspathResource(String location) {
this.location = location;
}
@Override
public InputStream getResource() {
return this.getClass().getClassLoader().getResourceAsStream(location);
}
}
DocumentReader类
public class DocumentReader {
/**
* 创建Document对象
*
* @param inputStream
* @return
*/
public static Document createDocument(InputStream inputStream) {
Document document = null;
try {
SAXReader reader = new SAXReader();
document = reader.read(inputStream);
return document;
} catch (DocumentException e) {
e.printStackTrace();
}
return null;
}
}
ReflectUtils
public class ReflectUtils {
/**
* 使用构造器创建bean的实例
*
* @param beanClassName
* @param args
* @return
*/
public static Object createObject(Class<?> clazz, Object... args) {
try {
// TODO 可以根据输入参数获取指定构造参数的构造方法
Constructor<?> constructor = clazz.getConstructor();
// 默认调用无参构造进行对象的创建
return constructor.newInstance(args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void setProperty(Object beanInstance, String name, Object valueToUse) {
try {
Class<?> clazz = beanInstance.getClass();
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(beanInstance, valueToUse);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Class<?> getTypeByFieldName(String beanClassName, String name) {
try {
Class<?> clazz = Class.forName(beanClassName);
Field field = clazz.getDeclaredField(name);
return field.getType();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void invokeMethod(Object beanInstance, String initMethod) {
try {
if (initMethod == null || "".equals(initMethod)) {
return;
}
Class<?> clazz = beanInstance.getClass();
Method method = clazz.getDeclaredMethod(initMethod);
// 设置允许访问私有方法和变量,此处也称之为暴力破解
method.setAccessible(true);
method.invoke(beanInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
}
XmlBeanDefinitionReader 类
public class XmlBeanDefinitionReader {
private BeanDefinitionRegistry beanDefinitionRegistry;
public XmlBeanDefinitionReader(BeanDefinitionRegistry beanDefinitionRegistry) {
this.beanDefinitionRegistry = beanDefinitionRegistry;
}
public void loadBeanDefinitions(InputStream inputStream) {
Document document = DocumentReader.createDocument(inputStream);
XmlBeanDefinitionDocumentReader documentReader = new XmlBeanDefinitionDocumentReader(beanDefinitionRegistry);
documentReader.registerBeanDefinitions(document.getRootElement());
}
}
XmlBeanDefinitionDocumentReader 类
public class XmlBeanDefinitionDocumentReader {
private BeanDefinitionRegistry beanDefinitionRegistry;
public XmlBeanDefinitionDocumentReader(BeanDefinitionRegistry beanDefinitionRegistry) {
this.beanDefinitionRegistry = beanDefinitionRegistry;
}
@SuppressWarnings("unchecked")
public void registerBeanDefinitions(Element rootElement) {
// 获取和自定义标签(比如mvc:interceptors)
List<Element> elements = rootElement.elements();
for (Element element : elements) {
// 获取标签名称
String name = element.getName();
if (name.equals("bean")) {
// 解析默认标签,其实也就是bean标签
parseDefaultElement(element);
} else {
// 解析自定义标签,比如mvc:interceptors标签回去
parseCustomElement(element);
}
}
}
@SuppressWarnings("unchecked")
private void parseDefaultElement(Element beanElement) {
try {
if (beanElement == null)
return;
// 获取id属性
String id = beanElement.attributeValue("id");
// 获取name属性
String name = beanElement.attributeValue("name");
// 获取class属性
String clazzName = beanElement.attributeValue("class");
if (clazzName == null || "".equals(clazzName)) {
return;
}
Class<?> clazzType = Class.forName(clazzName);
// 获取init-method属性
String initMethod = beanElement.attributeValue("init-method");
// 获取scope属性
String scope = beanElement.attributeValue("scope");
scope = scope != null && !scope.equals("") ? scope : "singleton";
String beanName = id == null ? name : id;
beanName = beanName == null ? clazzType.getSimpleName() : beanName;
// 创建BeanDefinition对象
// 此次可以使用构建者模式进行优化
BeanDefinition beanDefinition = new BeanDefinition(clazzName, beanName);
beanDefinition.setInitMethod(initMethod);
beanDefinition.setScope(scope);
// 获取property子标签集合
List<Element> propertyElements = beanElement.elements();
for (Element propertyElement : propertyElements) {
parsePropertyElement(beanDefinition, propertyElement);
}
// 注册BeanDefinition信息
beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void parsePropertyElement(BeanDefinition beanDefination, Element propertyElement) {
if (propertyElement == null)
return;
// 获取name属性
String name = propertyElement.attributeValue("name");
// 获取value属性
String value = propertyElement.attributeValue("value");
// 获取ref属性
String ref = propertyElement.attributeValue("ref");
// 如果value和ref都有值,则返回
if (value != null && !value.equals("") && ref != null && !ref.equals("")) {
return;
}
/**
* PropertyValue就封装着一个property标签的信息
*/
PropertyValue pv = null;
if (value != null && !value.equals("")) {
// 因为spring配置文件中的value是String类型,而对象中的属性值是各种各样的,所以需要存储类型
TypedStringValue typeStringValue = new TypedStringValue(value);
Class<?> targetType = ReflectUtils.getTypeByFieldName(beanDefination.getClazzName(), name);
typeStringValue.setTargetType(targetType);
pv = new PropertyValue(name, typeStringValue);
beanDefination.addPropertyValue(pv);
} else if (ref != null && !ref.equals("")) {
RuntimeBeanReference reference = new RuntimeBeanReference(ref);
pv = new PropertyValue(name, reference);
beanDefination.addPropertyValue(pv);
} else {
return;
}
}
private void parseCustomElement(Element element) {
// TODO Auto-generated method stub
}
}
BeanFactory 接口
public interface BeanFactory {
Object getBean(String name);
Object getBean(Class<?> type, String name);
}
AutowireCapableBeanFactory 接口继承BeanFactory
public interface AutowireCapableBeanFactory extends BeanFactory{
}
ListableBeanFactory 接口 继承BeanFactory
public interface ListableBeanFactory extends BeanFactory {
}
AbstractBeanFactory 类继承DefaultSingletonBeanRegistry 实现BeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
@Override
public Object getBean(String name) {
Object bean = doGetBean(name, null);
return bean;
}
@Override
public Object getBean(Class<?> type, String name) {
Object bean = doGetBean(name, type);
return bean;
}
private Object doGetBean(String name, Class<?> type) {
// 先查询单例bean集合是否存在该bean实例
Object singleton = getSingleton(name);
// 有则直接返回
if (singleton != null) {
return singleton;
}
// 没有则需要查询BeanDefinition集合中是否存在该BeanDefinition
BeanDefinition beanDefinition = getBeanDefinition(name);
// 没有BeanDefinition则返回null
if (beanDefinition == null) {
return null;
}
// 有BeanDefinition则判断是单例还是多例
if (beanDefinition.isSingleton()) {
singleton = createBean(beanDefinition);
addSingleton(name, singleton);
} else if (beanDefinition.isPrototype()) {
singleton = createBean(beanDefinition);
}
return singleton;
}
public abstract Object createBean(BeanDefinition beanDefinition);
public abstract BeanDefinition getBeanDefinition(String name);
}
AbstractAutowireCapableBeanFactory 类继承AbstractBeanFactory 实现AutowireCapableBeanFactory 接口
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
@Override
public Object createBean(BeanDefinition beanDefinition) {
// 实例化 new
Object bean = createInstance(beanDefinition);
if (bean == null)
return null;
// 属性填充 set
populateBean(bean, beanDefinition);
// 初始化 init
initBean(bean, beanDefinition);
return bean;
}
private void initBean(Object bean, BeanDefinition beanDefinition) {
// TODO Aware接口会在此时被处理
invokeInitMethod(bean, beanDefinition);
}
private void invokeInitMethod(Object bean, BeanDefinition beanDefinition) {
// bean标签配置了init-method属性
String initMethod = beanDefinition.getInitMethod();
if (initMethod == null || initMethod.equals("")) {
return;
}
ReflectUtils.invokeMethod(bean, initMethod);
// TODO bean标签实现了InitializingBean接口
}
private void populateBean(Object bean, BeanDefinition beanDefinition) {
List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
for (PropertyValue pv : propertyValues) {
String name = pv.getName();
Object value = pv.getValue();
Object valueToUse = null;
if (value instanceof TypedStringValue) {
TypedStringValue typedStringValue = (TypedStringValue) value;
String stringValue = typedStringValue.getValue();
Class<?> targetType = typedStringValue.getTargetType();
if (targetType == String.class) {
valueToUse = stringValue;
} else if (targetType == Integer.class) {
valueToUse = Integer.parseInt(stringValue);
} // ....
} else if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference reference = (RuntimeBeanReference) value;
String ref = reference.getRef();
// 创建一个bean的时候,根据依赖注入情况,自动去创建另一个bean去注入
valueToUse = getBean(ref);
}
ReflectUtils.setProperty(bean, name, valueToUse);
}
}
private Object createInstance(BeanDefinition beanDefinition) {
// TODO 可以通过静态工厂去创建????
// TODO 可以通过实例工厂去创建????
try {
String clazzName = beanDefinition.getClazzName();
Class<?> clazzType = resolveClass(clazzName);
Object bean = ReflectUtils.createObject(clazzType);
return bean;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Class<?> resolveClass(String clazzName) {
try {
Class<?> clazz = Class.forName(clazzName);
return clazz;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
BeanDefinitionRegistry 接口
public interface BeanDefinitionRegistry {
BeanDefinition getBeanDefinition(String name);
void registerBeanDefinition(String name, BeanDefinition beanDefinition);
}
SingletonBeanRegistry 接口
public interface SingletonBeanRegistry {
Object getSingleton(String name);
void addSingleton(String name, Object bean);
}
DefaultSingletonBeanRegistry 实现了SingletonBeanRegistry 接口
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
// 只有单例的bean才需要放入Map集合中进行保存管理
private Map<String, Object> singletonObjects = new HashMap<String, Object>();
@Override
public Object getSingleton(String name) {
return this.singletonObjects.get(name);
}
@Override
public void addSingleton(String name, Object bean) {
this.singletonObjects.put(name, bean);
}
}
DefaultListableBeanFactory 继承AbstractAutowireCapableBeanFactory 实现BeanDefinitionRegistry 接口
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
private Map<String, BeanDefinition> beanDefinitions = new HashMap<String, BeanDefinition>();
@Override
public BeanDefinition getBeanDefinition(String name) {
return this.beanDefinitions.get(name);
}
@Override
public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
this.beanDefinitions.put(name, beanDefinition);
}
}
BeanDefinition 类
public class BeanDefinition {
private String clazzName;//对应classname
private String beanName;//对应 id
private String initMethod;//对应 init-method
//该信息是默认的配置,如果不配置就默认是singleton
private String scope;//对应 scope
private static final String SCOPE_SINGLETON = "singleton";
private static final String SCOPE_PROTOTYPE = "prototype";
/**
* bean中的属性信息
*/
private List<PropertyValue> propertyValues = new ArrayList<>();
public BeanDefinition(String clazzName, String beanName) {
this.beanName = beanName;
this.clazzName = clazzName;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getInitMethod() {
return initMethod;
}
public void setInitMethod(String initMethod) {
this.initMethod = initMethod;
}
public List<PropertyValue> getPropertyValues() {
return propertyValues;
}
public void addPropertyValue(PropertyValue propertyValue) {
this.propertyValues.add(propertyValue);
}
public String getClazzName() {
return clazzName;
}
public void setClazzName(String clazzName) {
this.clazzName = clazzName;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public void setPropertyValues(List<PropertyValue> propertyValues) {
this.propertyValues = propertyValues;
}
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope);
}
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(this.scope);
}
}
PropertyValue 类
public class PropertyValue {
private String name;
private Object value;
public PropertyValue(String name, Object value) {
super();
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
public class RuntimeBeanReference {
private String ref;
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public RuntimeBeanReference(String ref) {
super();
this.ref = ref;
}
}
TypedStringValue 类
public class TypedStringValue {
private String value;
private Class<?> targetType;//value 的目标类型
public TypedStringValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Class<?> getTargetType() {
return targetType;
}
public void setTargetType(Class<?> targetType) {
this.targetType = targetType;
}
}
UserDao 接口
public interface UserDao {
List<User> queryUserList(String sqlId, Object param);
}
UserDaoImpl 类 实现UserDao 接口
public class UserDaoImpl implements UserDao {
private DataSource dataSource;
private Properties properties = new Properties();
// 初始化方法
public void init() {
if (!properties.isEmpty()) {
return;
}
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("sqlmapping.properties");
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public List<User> queryUserList(String sqlId, Object param) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
connection = dataSource.getConnection();
// 定义sql语句 ?表示占位符
String sql = properties.getProperty("db.sql." + sqlId);
System.out.println("SQL:" + sql);
System.out.println("参数:" + param);
// 获取预处理 statement
preparedStatement = connection.prepareStatement(sql);
// 设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的
if (param instanceof Integer) {
// ...
} else if (param instanceof String) {
preparedStatement.setObject(1, param.toString());
} else {
Class<?> clazz = param.getClass();
String params = properties.getProperty("db.sql." + sqlId + ".paramnames");
String[] paramArray = params.split(",");
for (int i = 0; i < paramArray.length; i++) {
String name = paramArray[i];
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
Object value = field.get(param);
preparedStatement.setObject(i + 1, value);
}
}
// 向数据库发出 sql 执行查询,查询出结果集
rs = preparedStatement.executeQuery();
// 遍历查询结果集
List<User> results = new ArrayList<User>();
Class<?> clazz = User.class;
while (rs.next()) {
User instance = (User) clazz.newInstance();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
String columnName = metaData.getColumnName(i + 1);
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(instance, rs.getObject(i + 1));
}
results.add(instance);
}
return results;
} catch (
Exception e) {
e.printStackTrace();
} finally {
// 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block e.printStackTrace();
}
}
}
return null;
}
}