我们开发过web项目的都发现,持久化框架在改变,前台的mvc框架也在改变,但是始终再用的就是spring,为什么这么说呢。轻量级,方便,关键就是这个容器了吧,这也是spring依然这么流行的原因吧。
说道容器,我们会想到List,Map,Queue,但是这些基本容器之外,spring又给我们提供了一个更加全面的容器,用来加载我们需要加载的类文件。
容器实例
接口
public interface BeanFactory {
/**
* 获取一个对象
* @param key 对象对应的key
* @return 对象
*/
public Object getBean(String key);
/**
* 获取所有的javaBean对象
* @return
*/
public Map<String,Object> getAllBean();
/**
* 打印所有的javaBean对象
*/
public void printAllBean();
/**
* 查询有多少个对象
* @return
*/
public int size();
/**
* 打印所有的Bean的类型
*/
public void printTypeName();
/**
* 移除一个Bean对象
* @param key
*/
public void remove(String key);
public Object put(String key,Object value);
}
实现类
public class ClassPathXmlApplicationContext implements BeanFactory {
private boolean isAop = false;
private Map<String, Object> beans = new HashMap<String, Object>();
/**
* 构造函数
* @throws JDOMException
* @throws IOException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
public ClassPathXmlApplicationContext() throws JDOMException, IOException,
InstantiationException, IllegalAccessException,
ClassNotFoundException {
SAXBuilder sb = new SAXBuilder();
//读取配置文件,获取document
Document doc = sb.build(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("beans.xml"));
//获取跟节点
Element root = doc.getRootElement();
//获取根节点aop节点
Element aopElement = (Element) root.getChildren("aop").get(0);
isAop = Boolean.parseBoolean(root.getAttributeValue("isaop"));
//获取bean的集合
List list = root.getChildren("bean");
//获取aspectbefore的集合
List spectbefore = root.getChildren("aspectbefore");
//获取aspectafter集合
List aspectafter = root.getChildren("aspectafter");
//将获取到的集合包含到map中
if (aspectafter != null) {
beans.put("aspectbefore", spectbefore);
}
if (aspectafter != null) {
beans.put("aspectafter", aspectafter);
}
//循环获取的元素,找到他们的properties
for (int i = 0; i < list.size(); i++) {
Element element = (Element) list.get(i);
String id = element.getAttributeValue("id");
String clazz = element.getAttributeValue("class");
Object obj = Class.forName(clazz).newInstance();
beans.put(id, obj);
// 添加属性
for (Element propertyElement : (List<Element>) element
.getChildren("property")) {
//获取Property中的name
String name = propertyElement.getAttributeValue("name");
//name指向的类
String bean = propertyElement.getAttributeValue("ref");
Object beanObject = beans.get(bean);
//根据name设置set方法的名称
String methodName = "set" + name.substring(0, 1).toUpperCase()
+ name.substring(1);
Method m = null;
try {
//根据名称和类的接口来获取名称(这里的类必须要集成接口)
m = obj.getClass().getMethod(methodName,
beanObject.getClass().getInterfaces()[0]);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
try {
//执行set方法,讲beanObject注入到obj中
m.invoke(obj, beanObject);
} catch (IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
@Override
public Object getBean(String key) {
return beans.get(key);
}
/**
* 获取beans中所有的对象
*/
@Override
public Map<String, Object> getAllBean() {
Map<String, Object> beanMap = new HashMap<>();
Iterator iterator = beans.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Object> entry = (Entry) iterator.next();
beanMap.put(entry.getValue().getClass().getSimpleName(),
entry.getValue());
}
return beanMap;
}
/**
* 打印所有的bean
*/
@Override
public void printAllBean() {
//获取所有的bean
Set<Entry<String, Object>> entrySet = beans.entrySet();
//讲所有的bean的名称添加到setList中
Set<String> setList = new HashSet<String>();
{
//循环遍历
Iterator<Entry<String, Object>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Entry<String, Object> entry = (Entry<String, Object>) iterator
.next();
setList.add(entry.getKey());
}
}
for (String string : setList) {
System.out.println(string);
}
}
/**
* 获取bean的个数
*/
@Override
public int size() {
return beans.size();
}
@Override
public void printTypeName() {
Set<String> set = new HashSet<String>();
Set<Entry<String, Object>> setEntry = beans.entrySet();
{
Iterator iterator = setEntry.iterator();
while (iterator.hasNext()) {
Entry<String, Object> entry = (Entry<String, Object>) iterator
.next();
set.add(entry.getValue().getClass().getSimpleName());
}
}
for (String key : set) {
System.out.println(key);
}
}
/**
* 根据key移除一个对象
*/
@Override
public void remove(String key) {
beans.remove(key);
}
/**
* 加入一个实体对象
*/
@Override
public Object put(String key, Object value) {
return beans.put(key, value);
}
}
配置文件
<beans>
<bean id="UserDao" class="UserDaoImpl.UserDaoImpl" />
<bean id="userService" class="service.UserService">
<property name="userDao" ref="UserDao" />
</bean>
<aop isaop="true"></aop>
</beans>
Bean
““java
public class UserDaoImpl implements UserDao {
@Override
public void addUser(User user) {
System.out.println(user.getUsername());
}
}
##客户端调用
```java
BeanFactory factory = new ClassPathXmlApplicationContext();
User user = new User();
UserDao userDao = (UserDao)factory.getBean("UserDao");
UserDao userDao2 = new UserDaoImpl();
factory.put("userDao2", userDao2);
for (int i = 0; i < 20; i++) {
factory.put("user" + i, new User());
}
factory.printAllBean();
System.out.println("--------------");
factory.printTypeName();
小结
其实说的容器,无非就是从读取配置文件,然后获取节点信息,根据节点信息,获取类,根据name获取set方法,执行set方法将类注入。主要用的就是反射。