1:Bean容器的理解

1.1 :容器基础

在Ioc应用中,容器扮演了非常重要的角色,它负管理对象定义维护,对象的创建,对象之间的关系等等,开发人员只需要调用容器的context即可获得所需要的对象实例,而不再需要在程序中通过New关键字去创建了,关于该技术的优点,,网上一大堆,在此就不再罗嗦了,下面我们主要从技术层面谈谈容器的实现原理


1.2理解注入

相信从事Java开发的人都知道,一个普通的Java Bean的组成结构:成员字段,Get/Set方法,构造方法和其他方法。在实际使用的过程中,往往需要调用Bean的Set方法或业务方法,将所需要的值传入对象的内部,从而达到影响对象的后续其他操作,在没有容器的情况下,我们往往需要调用对象的set方法去放值;但是有了容器之后,它则以代理的方式将所需的值放入对象内部,调用本质未变,只是调用者不同而已。业界将这个容器调用对象赋值的方式,取了一个很形象化的称谓:注入


1.3注入什么

上文谈到了 “注入” 一词,这个词从字眼来是个动词,如果补充完整,这句话可以表达为:容器将参数注入对象内部,这句话的着力点:参数。按照Java一切都是对象思想,参数也应是对象,在注入之前, Bean容器是需要准备好相应的参数对象,那么对于容器而言,是如何构造参数对象的呢?依据需要,参数可初步分为以下几种类型

1:文本类型:(包括文本转换型,列如:字符串“5”,目标需要是一个Integer,则可以转换)

2:Class类型: 直接通过反射方式newInstance方式构造参数对象

3:引用类型:容器通过一个Id获取另一个Bean的实例作为参数

 1.4怎么注入

上节谈到将容器参数注入到对象内部,那么是必须以对象所支持的方式放入,最直接有效的方式就是直接调用对象的方法,但是由于对象具有多样性,显然通过直接调用的方式显然是不太现实。


上图的方式,肯定行不现实,如果需要存在多个Bean类型,还不知道需要import多个类型呢,现在只能寻找一种非传统途径才能达到目标。在我们的JDK开发包中,就存在这么一种非传统方式:反射(感谢JDK的开发者们),可以在java.lang.reflect包下找到相应的API。下面列举一下反射技术将会用到的几个重要的类:

1: java.lang.Class

Java源文件被编译成二进制文件,虚拟机在运行的时候,将加载该二进制内容进内存,Java并以Class对象进行表征,我们可以比较容易获得该定义性对象。

A: 获取方式一,通过类的名字获得,例如:

Classclazz = Class.forName(“test.Man”) ;                              

B: 获取方式二,通过对象实例获得

Man man = new Man();

Class clazz = man.getClass();

2: java.lang.reflect.Constructor

Bean构造函数的定义对象,在Class对象上,可以获得构造函数的定义对象。

Class clazz = Class.forName(“test.Man”);

上图定义的类中包含两个构造函数,那么下面程序代码则可以获取对应的构造对象

Constructor constructor1 = clazz.getDeclaredConstructor(new Class[0])

Constructor constructor2 = clazz.getDeclaredConstructor(new Class[]{java.lang.String.class})

在得到构造函数之后,就可以在此基础上构建对象实例了

Man man1=(Man)constructor1.newInstance(new Object[0]);

Man man2=(Man)constructor2.newInstance(new Object[]{“Chris”});

3: java.lang.reflect.Field

Bean字段定义对象,如上图类中的 name属性,在Class对象上,可以获得成员字段的定义对象。

Field field = clazz. getDeclaredField(“name”);

通过字段对象.set方法,可以为对象成员字段赋值,但是由于当前字段是私有的,外部是可以不访问的,但是稍微做点改变,依然还是可以访问的。

field.setAccessible(true);

field.set(man1, “Chris”);

4:java.lang.reflect.Method;

Bean方法定义对象,如上图类中的 setName方法,在Class对象上,可以获得成员方法的定义对象。

Method method = clazz.getDeclaredMethod (“setName”, new Class[]{ava.lang.String.class } );

既然能得到方法的定义对象,那么就可以通过它为对象赋值

method.Invoke(man1,new Object[]{“Chris”} );

到此,我们已了解Java反射技术是如何将参数值放入对象内部的,这个是Ioc容器实现的重要基础。

1.5容器指令

Bean容器之所以能准确构建我们需要的对象,并将参数注入其内部,那是因为容器得知了正确的指令(告诉容器该干什么),例如构建对象指令,注入指令等等,针对每个Bean,都有可能存在这些容器指令的,很明显这些指令是在围绕Bean对象进行的,并作为其组成部分存在于容器中。

 1.6定义指令

上一节中,我们探讨了容器指令的概念,并且了解指令的目标对象是Bean.那应指令到底有哪些呢?对于Ioc容器来说,一个重要指令就是:注入.从1.4节中我们从反射技术探讨如何注入时,提到了注入有三种不同的方式,那么我们可以初略定义注入三个指令:1字段注入指令 2构造方法注入指令 3:方法调用注入指令。除了注入指令,那么还有没有其他指令呢?应该是有的,比如还可以定义:单例指令,方法拦截指令(AOP)等等,当然也可以根据具体的情况,定义需要的一些其他指令,下面给个指令列表罗列几个概要的

       指令名

                            指令内容

         类别

字段注入指令

将参数值传给Bean的字段

          注入  

构造方法注入指令

通过构造方法,将参数值传入Bean的内部

          注入     

方法调用注入指令

通过调用方法,将参数值传入Bean的内部

          注入 

单例指令

是否创建一个对象

          构造

方法调用拦截指令

是否为某个方法调用添加拦截

          拦截

1.7指令导入
指令是一个名词,理解为:发出者和接收者以及内容(类似消息)。Bean容器在收到指令后,并指令内容的方式加工Bean对象。在程序里要向一个对象传送指令,最直接有效的方式就是调用它的方法,将指令以参数的形式传入其内部. 我们可以这一告知的方式理解为:导入或注册。

下面给一段伪代码可能更容易理解

Parameter parameter=newTextParameter(“Chris”);//创建指令内容

 InjectionField field =newInjectionField(“name”,parameter);//创建指令

 BeanContainer.register(Man.class, field);//导入指令

 1.8参数指令

在第1.4节中,我们提到了:容器依据注入指令将参数值放入Bean对象内部,既然容器能操作参数对象,那么参数信息是如何进入容器内部呢?如果把注入指令当作邮件,那么参数就是邮件的内容,很显然参数是作为指令的部分并存。

从上图中可以看出,不同的指令携带的参数个数可能不一样的,这点其实也好理解,这个等同于理解方法的参数个数,只不过我们这里提的参数与我们方法调用的参数是有点不同,它是给容器理解的,既然参数是对象,那么对象就该有类型.我们程序里的对象类型是千变万化的,各不相同的,如果直接参照Java通常的参数方式,Bean容器肯定是无法接受的,因此必须换种思路设计一套稳定的,容器能理解的参数对象。因此可以把我们所讲的参数理解为参数指令,是告诉容器如何依据这个指令获取一个匹配的参数值.由于参数具有多样性,有可能参数指令提供的参数值不能满足目标,那么容器应该提供一种转换策略,例如:外部传入的参数为字符串“5”,而实际注入需要一个int类型,那么应该将此转换

 1.9指令形态

上节中,我们提到了容器指令,在实际开发过程中,这些指令可能以多种形态存在,例如XML方式配置指令,或Java注解的方式存在,更有可能以properties属性文件表现,这好比水一样,在不同的温度下以固态,液态,气态形式存在,但是本质都是H2O,我们所说的指令形态也是雷同道理,这应该也算一种多态现象吧。对于Bean容器而言,以Java Bean形态出现的指令是最容易让容器理解的,而其他形态则可以通过技术手段转换为该形态,这样保障了核心基础稳定不变,下面有一个结构图说明关系


1.10容器工序

Bean容器的一个主要的职责就是加工Bean,对外部提供对象实例,所以我们称之Ioc容器为Bean工厂。既然是类比为一座工厂,那工厂是怎么样的呢?工厂一般会依据不同职责设置一些流水车间,每个车间针对物件做一道工序(也可多道)。那么我们的容器内部的工作原理,也应类似吧,对于一个Bean对象来说,可能需要经过加工工序有:类的改造,对象的构造,参数的注入等等,因此依据这些不同的工序,我们也可以依此设置Bean的加工车间。


 

更多接口代码与demo,可以从这里下载

下载地址1:http://pan.baidu.com/share/home?uk=2218126399
下载地址2:http://dl.vmall.com/c0u7lix55w


 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值