Spring、Spring依赖注入与编码剖析Spring依赖注入的原理
Spring依赖注入
新建PersonIDao 和PersonDao底实现Save方法:
- public interface PersonIDao {
- public void save();
- }
- public class PersonDaoImpl implements PersonIDao{
- @Override
- public void save() {
- System.out.println("我是dao的Save方法");
- }
- }
在Bean.xml中注入PersonIDao,并将PersonIDao注入到PersonService中:
- <bean id="personIDao" class="cn.dao.impl.PersonDaoImpl" />
- <bean id="personIService" class="cn.server.impl.PersonServiceImpl">
- <property name="personIDao" ref="personIDao" />
- </bean>
在PersonService中添加PersonIDao类型属性并实现属性的set方法,然后调用PersonIDao的save方法
- public class PersonServiceImpl implements PersonIService {
- private PersonIDao personIDao;
- public PersonIDao getPersonIDao() {
- return personIDao;
- }
- public void setPersonIDao(PersonIDao personIDao) {
- this.personIDao = personIDao;
- }
- @Override
- public void save() {
- personIDao.save();
- }
- }
然后测试:
- @Test
- public void testSave() {
- AbstractApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
- PersonIService personIService=(PersonIService)ac.getBean("personIService");
- personIService.save();
- }
编码剖析Spring依赖注入的原理
通过编码的方法式来剖析Spring 依赖注入的原理方法,新建PropertyDefinition类用来承载Bean中注入的property的属性:
- public class PropertyDefinition {
- private String name;
- private String ref;
- public PropertyDefinition(){}
- public PropertyDefinition(String name, String ref) {
- super();
- this.name = name;
- this.ref = ref;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getRef() {
- return ref;
- }
- public void setRef(String ref) {
- this.ref = ref;
- }
- }
新建BeanDefinition用来承载解析到的Bean属性
- public class BeanDefinition {
- private String id;
- private String className;
- private List<PropertyDefinition> properties=new ArrayList<PropertyDefinition>();
- public BeanDefinition(){}
- public BeanDefinition(String id, String className) {
- this.id = id;
- this.className = className;
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getClassName() {
- return className;
- }
- public void setClassName(String className) {
- this.className = className;
- }
- public List<PropertyDefinition> getProperties() {
- return properties;
- }
- public void setProperties(List<PropertyDefinition> properties) {
- this.properties = properties;
- }
- }
新建OtherClassPathXMLApplicationContext 用来解析bean.xml
- public class OtherClassPathXMLApplicationContext {
- private List<BeanDefinition> list=new ArrayList<BeanDefinition>();
- private Map<String,Object> beans=new HashMap<String, Object>();
- public OtherClassPathXMLApplicationContext(String fileName){
- this.readXML(fileName);
- this.instanceBeans();
- this.instanceProperties();
- }
- private void instanceBeans(){
- for(BeanDefinition bean : list){
- try {
- // 创建Bean实例,并放到Map中
- if(bean.getClassName()!=null && !bean.getClassName().trim().equals("")){
- beans.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- private void instanceProperties(){
- for(BeanDefinition beanDefinition : list){
- Object bean=beans.get(beanDefinition.getId());
- if(bean!=null){
- try {
- // 获取bean下所有的属性定义描述
- PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
- for(PropertyDefinition propertyDefinition : beanDefinition.getProperties()){
- for(PropertyDescriptor propertyDescriptor : ps){
- // 如果bean下的属性名字与当前的BeanDefinition下的属性名称一样的话,则将引用对象注入到属性
- if(propertyDefinition.getName().equals(propertyDescriptor.getName())){
- Method setter=propertyDescriptor.getWriteMethod(); // 获取Bean的所有写入的方法 即 setter方法
- setter.setAccessible(true); // true: 直接访问私有属性,将例子中的私有属性改值。
- Object value=beans.get(propertyDefinition.getRef());
- setter.invoke(bean, value); // 把引用对象注入属性
- break;
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- private void readXML(String fileName){
- SAXReader saxReader = new SAXReader();
- Document doc=null;
- try{
- // JAVA里面对于类进行调用配置资源的文件数据,以this.getClass().getResourceAsStream()来读取比较合适。
- // 路径采用相对路径直接可以从工程的path路径去找。
- URL xmlpath=this.getClass().getClassLoader().getResource(fileName);
- doc=saxReader.read(xmlpath);
- Map<String,String> nsMap=new HashMap<String,String>();
- nsMap.put("ns", "http://www.springframework.org/schema/beans"); // 加入命名空间
- XPath xsub=doc.createXPath("//ns:beans/ns:bean"); // 创建 beans/bean的查询路径
- xsub.setNamespaceURIs(nsMap); // 设置命名空间
- List beans=xsub.selectNodes(doc); // 获取文档下的所有bean节点
- for(Object node : beans){
- Element element=(Element)node;
- String id=element.attributeValue("id");
- String className=element.attributeValue("class");
- BeanDefinition bean=new BeanDefinition(id,className);
- // 编码剖析Spring依赖注入的原理
- // 加载bean下的Property
- XPath xproperty=element.createXPath("ns:property"); // 为xproperty 添加查询路径
- xproperty.setNamespaceURIs(nsMap);
- List properties=xproperty.selectNodes(element); // 查询出bean下的所有property
- for(Object propertyNode : properties){
- Element propertyElement=(Element)propertyNode;
- String name=propertyElement.attributeValue("name");
- String ref=propertyElement.attributeValue("ref");
- bean.getProperties().add(new PropertyDefinition(name, ref));
- }
- list.add(bean);
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- // 通过Id名称,获取Bean
- public Object getBean(String name){
- return beans.get(name);
- }
- }
测试代码:
- @Test
- public void testSave2() {
- OtherClassPathXMLApplicationContext ac = new OtherClassPathXMLApplicationContext("beans.xml");
- PersonIService personIService=(PersonIService)ac.getBean("personIService");
- personIService.save();
- }
Spring、Spring依赖注入与编码剖析Spring依赖注入的原理的更多相关文章
- (转)编码剖析Spring依赖注入的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...
- (转)编码剖析Spring装配基本属性的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52856465 上回我们已经讲到了Spring依赖注入的第一种方式,现在我们来详解第二种方式,须 ...
- (转)编码剖析Spring管理Bean的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52832434 在Spring的第一个案例中,我们已经知道了怎么将bean交给Spring容器进 ...
- (转)编码剖析@Resource注解的实现原理
http://blog.csdn.net/yerenyuan_pku/article/details/52860046 上文我们已经学会使用@Resource注解注入属性.学是学会了,但也仅限于会使用 ...
- Spring、编码剖析Spring管理Bean的原理
引入dom4j jar包 1.新建Person接口和PersonBean public interface PersonIService { public void helloSpring(); } ...
- Spring(八)编码剖析@Resource注解的实现原理
配置文件beans2.xml <?xml version="1.0" encoding="UTF-8"? > <beans xmlns=&qu ...
- Spring第三弹—–编码剖析Spring管理Bean的原理
先附一下编写的Spring容器的执行结果: 代码如下: 模拟的Spring容器类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
- 编码剖析Spring管理bean的原理
project目录 MyClassPathXMLApplicationContext读取xml,以及实例化bean. 因为是一开始实例化配置文件所有bean,所以需要构造器完成这些工作. packag ...
- Spring2.5学习3.2_编码剖析@Resource注解的实现原理
首先看一下J2EE提供的@Resource注解:该注解默认安照名称进行装配,名称能够通过name属性进行指定, 假设没有指定name属性,当注解写在字段上时,默认取字段名进行依照名称查找,假设注解写在 ...
随机推荐
- racle undo 解析
racle undo 解析 声明一下:关于oracle的文章基于boobooke小布老师视频,在我学习的过程中,每有体会拿来分享,虽然从理解到整理分享很耗时,但我想这样的学习是扎实的. Undo是干嘛 ...
- C++ new和delete实现原理——new和delete最终调用malloc和free
new和delete最终调用malloc和free,关于malloc和free实现原理参见这篇文章: http://blog.csdn.net/passion_wu128/article/detail ...
- 设置edittext的hint位置
<EditText android:id="@+id/edt_content" android:layout_width="fill_parent" an ...
- Android常用代码
1.图片旋转 Bitmap bitmapOrg = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable. ...
- HBase 1、HBase介绍和工作原理
HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利用了Google文件 ...
- Number Sequence(kmp)
Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- A Game with Colored Balls
题目链接 题意: 给一个长度为n的字符串,每次删除字母同样切连续的串,假设有多个,删除最左边的.最长的串.每次删除输出串的字母,每一个字母的下标(1-n) N (1 ≤ N ≤ 106),串仅仅包含r ...
- javascript模式——Mixin
Mixin是一种扩展收集功能的方式,能提高代码的复用率. 在javascript中,原型可以继承于其它对象的原型,并且可以为任意数量的实例定义属性.可以利用这一点来促进函数的复用. 下面一段代码就是将 ...
- javascript设计模式——Singleton
单例模式指的是只能被实例化一次. 推荐阅读: http://blog.mgechev.com/2014/04/16/singleton-in-javascript/ 比较通用的一种Singleton模 ...
- HTML——CSS样式表&布局页面
CSS样式表: 一.作用:美化网页,页面布局. 二.分类: 内联,写在body里标签style=""里面的样式,优点是控制精确,可重用性差. 内嵌,嵌在网页的head里面,可重用性 ...