厦门北京网站建设,python做网站教程,怎么增加网站的外链,襄阳网站制作依赖注入之setter注入#xff1a;
依赖注入是IOC具体的一种实现方式#xff0c; 这是针对资源获取的方式角度来说的#xff0c;之前我们是被动接受#xff0c;现在IOC具体的实现叫做依赖注入#xff0c;从代码的角度来说#xff0c;原来创建对象的时候需要new#xff0…依赖注入之setter注入
依赖注入是IOC具体的一种实现方式 这是针对资源获取的方式角度来说的之前我们是被动接受现在IOC具体的实现叫做依赖注入从代码的角度来说原来创建对象的时候需要new而现在并不需要这样做只需要将所依赖的对象给它设置相对应的方法set方法也行有参构造也行以我们设置好的方法来接受spring为我们所注入的对象
比如我们此时创建一个实体类其中包含id,age,name等属性那我们就说student对象是依赖于id/name/age这些属性的既然student依赖于这些属性那么我们就可以在IOC容器中为其进行赋值依赖注入通俗点说就是为类中的属性赋值的过程
student类
package xysfxy;public class student implements person {private Integer sid;private String sname;private Integer age;private String gender;public student() {}public Integer getSid() {return sid;}public void setSid(Integer sid) {this.sid sid;}public String getSname() {return sname;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}public void setSname(String sname) {this.sname sname;}public String getGender() {return gender;}public void setGender(String gender) {this.gender gender;}Overridepublic String toString() {return studnet{ sid sid , sname sname , age age , gender gender \ };}public student(Integer sid, String name, Integer age, String gender ) {this.ageage;this.snamesname;this.gendergender;this.sid sid;}
}如下所示当我们为student类中的name属性赋值注意name在这里是属性那么什么叫属性呢找到当前类中set和get方法把方法中的set和get去掉剩余部分的首字母变成小写的结果就是属性由于我们当前是给属性赋值因此需要寻找set方法 在spring.xml文件中为属性赋值
!-- property通过成员变量的set方法进行赋值name:设置需要赋值的属性名(和set方法有关)value设置为属性所赋的值--
bean idstudent1 classxysfxy.student property namesid value1001/propertyproperty namesname value张三/propertyproperty nameage value20/propertyproperty namegender value男/property
/bean创建测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;
import xysfxy.student;public class student_text {Testpublic void test(){ApplicationContext iocnew ClassPathXmlApplicationContext(applicantsContext.xml);student student ioc.getBean(student.class);System.out.println(student);}
}输出如下所示
studnet{sid1001, sname张三, age20, gender男}此时输出的结果正是我们上述所赋的值
依赖注入之构造器注入
在spring.xml文件中赋值
!-- 赋值时一定要与构造器中的属性相对应--
bean idstudent1 classxysfxy.student constructor-arg value1002/constructor-argconstructor-arg value李四/constructor-argconstructor-arg value19/constructor-argconstructor-arg value男/constructor-arg
/bean其他不变运行结果如下所示
studnet{sid1002, sname李四, age19, gender男}在上述student类中添加score属性并创建新的有参构造
//新的有参构造中使用score属性代替age属性
public student(Integer sid, String name, String gender , double score) {this.sid sid;this.snamename;this.gendergender;this.scorescore;}//原有参构造public student(Integer sid, String name, String gender, Integer age ) {this.sid sid;this.snamename;this.gendergender;this.ageage;
}//重写tostring方法Override
public String toString() {return student{ sid sid , sname sname \ , age age , gender gender \ , score score };
}//为新添加的属性设置set和get方法public double getScore() {return score;}public void setScore(double score) {this.score score;}spring.xml文件中的参数设置不变
bean idstudent1 classxysfxy.student constructor-arg value1002/constructor-argconstructor-arg value李四/constructor-argconstructor-arg value男/constructor-argconstructor-arg value24/constructor-arg/bean在当有参构造器中包含参数相同的情况下spring.xml文件中的第四个数据24既可以匹配给整形age也可以匹配给double类型的score,测试结果如下 我们发现默认情况下,24匹配给了score但事实我们是想实现将24匹配给年龄 那么该如何实现呢
关于这种情况网上的解决方法有很多: 方法1spring.xml文件的bean标签的最后一个属性值设置时,指定nameage方法2将有参构造中包含age的那个构造方法放在另一个的前面我使用第二种方式可以但第一种就会报错至于为什么不能两个方法通用我也很疑惑…
依赖注入之特殊值处理
字面量赋值
什么是字面量
例如
int a10;声明一个变量a,初始化为10此时a就不代表字母a了而是作为一个变量的名字当我们引用a的时候我们实际上拿到的值是10,而如果a是带引号的:“a”,那么它现在不是一个变量它就是代表a这个字母本身这就是字面量所以字面量没有引申含义就是我们看到的这个数据本身
举例
我们在spring.xml文件中设置gender属性的值为null:
bean idstudent1 classxysfxy.student property namesname value张三 /propertyproperty namesid value1002 /propertyproperty namegender valuenull /propertyproperty nameage value24 /property/bean输出如下所示
student{sid1002, sname李四, age24, gendernull, score0.0}我们发现gender最终输出的值就是null,那他表示的是null对象还是值为null的字符串呢
我们可通过下述代码进行测试如果没有报错则证明当前的null为值是null的字符串
System.out.println(student.getGender().toString());输出如下所示 如果它是null对象的话应该报错为空指针异常
正确的将属性设置为null对象的方法如下
bean idstudent1 classxysfxy.student property namesname value张三 /propertyproperty namesid value1002 /property!-- 将gender属性设置为null对象,使用null标签表示,由于该标签中的内容是空,因此我们可以写为单标签 --property namegendernull//property
/bean输出如下 xml实体
小于号在XML文档中用来定义标签的开始不能随便使用如下所示
我们想输出name的值是一个带的如果直接添加带符号在XML文档是不可行的 解决方案使用XML实体来代替lt;表示小于号gt;表示大于号修改上述代码如下所示 property namesname valuelt;张三gt; /property输出结果如下所示
此时的sname的值中的大括号和小括号都被显示出来
student{sid1002, sname张三, age11, gendernull, score0.0}关于特殊符号无法被解析的问题我们还有另外一种办法就是使用CDATA节CDATA中的C代表Character,是文本字符的含义CDATA就代表纯文本数据XML解析器看到CDATA就知道这里是纯文本就不会当做XML标签或属性来解析所以CDATA节中写什么都任意在IDE中我们可以通过快捷键使用这个功能CD[一定要大写]回车即可如下所示 property namesname value![CDATA[张三]]/value/property输出如下
student{sid1002, sname张三, age11, gendernull, score0.0}这种方式也可以正确的显示特殊字符但需要注意的是它是XML中一个特殊的标签我们不能将其当做value属性的值写在value属性的后面
依赖注入之为类类型的属性赋值
创建实体类班级
package poij;public class clazz {private Integer cid;private String name;public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid cid;}public String getName() {return name;}public void setName(String name) {this.name name;}public clazz(Integer cid,String name) {this.cid cid;this.namename;}public clazz() {}Overridepublic String toString() {return clazz{ cid cid , name name \ };}
}修改student类
//班级和学生之间是一对多的关系,将班级作为学生的一个属性加入到学生类中private clazz clazz;//并为其设置set和get方法public poij.clazz getClazz() {return clazz;}public void setClazz(poij.clazz clazz) {this.clazz clazz;}//重写toString方法Overridepublic String toString() {return student{ sid sid , sname sname \ , age age , gender gender \ , clazz clazz };}那么对于student类来说clazz属性该如何赋值呢
我们不能使用value对其进行赋值因为value是给字面量赋值的但clazz对应的是一个对象
那么该如何给类类型赋值呢
引用外部的bean给类类型赋值
修改spring文件中的代码
!-- 在给类为student的bean对象的clazz赋值时使用引用外部bean的方式
ref:引用IOC容器中的某个bean--
property nameclazz refclazz1/property!-- 创建类型为clazz的bean对象--
bean idclazz1 classpoij.clazzproperty namecid value1111/propertyproperty namename value菜鸟班/property
/bean输出如下所示 通过级联方式给类类型赋值
在mybatis中我们也曾经使用过级联的方式为其赋值也就是通过类.属性的方式对其进行赋值那么在spring中也可以使用该方法吗
如下所示尝试使用类.属性的方式直接赋值
property nameclazz.cid value2222/property
property nameclazz.name value卷心菜班/property运行报错虽然上述这种方法可以在mybatis中使用但是在spring中是不行的 使用级联方式的前提条件是要保证提前为clazz属性赋值或者实例化
方法1先赋值再修改
bean idstudent1 class poij.student property namesid value1001/propertyproperty namesname value张三/propertyproperty nameage value20/propertyproperty namegender value男/property!-- 先通过引用外部bean的方式为其赋值 --property nameclazz refclazz1/property!-- 再对上述 引用的bean对象的值进行修改--property nameclazz.cid value2222/propertyproperty nameclazz.name value卷心菜班/property/bean!-- 创建外部的bean对象--
bean idclazz1 classpoij.clazzproperty namecid value1111/propertyproperty namename value菜鸟班/property
/bean方法2在student类中对clazz进行实例化
private clazz clazz new clazz( );在spring.xml文件中可直接通过类.属性的方式进行赋值
property nameclazz.cid value2222/property
property nameclazz.name value卷心菜班/property上述任意一种输出均为如下所示
student{sid1001, sname张三, age20, gender男, clazzclazz{cid2222, name卷心菜班}}虽然以级联的方式也可以对类类型进行赋值但这种方法我们并不常用我们通常使用内部bean的方式下面我们就具体学习一下该方式如何使用
使用内部bean的方式为类类型赋值
修改spring.xml中的bean标签
bean idstudent1 class poij.student property namesid value1001/propertyproperty namesname value张三/propertyproperty nameage value20/propertyproperty namegender value男/property!-- 内部bean的方式为通过设置一个内部的bean对象而为clazz对象进行赋值--property nameclazz!-- 将为班级赋值的过程写在一个内部的bean标签中--bean idclazz_inner classpoij.clazzproperty namecid value333/propertyproperty namename value卷王班/property/bean/property
/bean输出如下所示
student{sid1001, sname张三, age20, gender男, clazzclazz{cid333, name卷王班}}内部bean就类似于我们在java中学过的内部类一样它只能在bean的内部进行使用那么内部bean可以通过IOC容器进行获取吗
修改测试类中的代码
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import poij.clazz;public class student_text {Testpublic void test(){ApplicationContext iocnew ClassPathXmlApplicationContext( spring.xml);//尝试获取内部beanclazz clazz1 ioc.getBean( clazz.class);System.out.println(clazz1);}
}输出如下所示
看来内部bean确实无法通过IOC容器直接获取 说到这里为类类型的属性赋值的三种方式我们已经说完了引用外部的bean以及使用内部bean是我们所推荐的方法第二种使用级联并不是我们所推荐的原因是它需要先赋值再修改这样好像并不是真正意义上的赋值而是修改已有的值
依赖注入之为数组类型的属性赋值
修改student类中的代码
//添加新的属性
private String [] hobby;//为新的属性编写set和get方法
public String[] getHobby() {return hobby;}public void setHobby(String[] hobby) {this.hobby hobby;}
//重写toString方法Overridepublic String toString() {return student{ sid sid , sname sname \ , age age , gender gender \ , clazz clazz , hobby Arrays.toString(hobby) };}在spring.xml中为hobby属性赋值
bean idstudent1 class poij.student property namesid value1001/propertyproperty namesname value张三/propertyproperty nameage value20/propertyproperty namegender value男/propertyproperty nameclazzbean idclazz_inner classpoij.clazzproperty namecid value333/propertyproperty namename value卷王班/property/bean/property!-- 为类型为数组的hobby属性赋值数组的值为字面量则使用value标签如果为对象类型则使用ref标签通过的id从而获取对应的bean --property namehobbyarrayvalue吃饭/valuevalue睡觉/valuevalue打豆豆/value/array/property/bean输出如下所示
student{sid1001, sname张三, age20, gender男, clazzclazz{cid333, name卷王班}, hobby[吃饭, 睡觉, 打豆豆]}依赖注入之为集合类型的属性赋值
修改clazz类
//1个班级可以有多个学生因此将学生作为属性添加到班级中是以集合的形式
private Liststudent students;//为其编写set和get方法
public Liststudent getStudents() {return students;}public void setStudents(Liststudent students) {this.students students;}//重写toString方法Overridepublic String toString() {return clazz{ cid cid , name name \ , students students };
}内部list集合为集合类型的属性赋值
修改spring.xml文件
!-- student1学生--
bean idstudent1 classpoij.studentproperty namesid value1/propertyproperty namesname value张三/propertyproperty nameage value20/propertyproperty namegender value女/propertyproperty namehobbyarrayvalue吃饭/valuevalue睡觉/value/array/property/bean!-- student2学生--
bean idstudent2 classpoij.studentproperty namesid value2/propertyproperty namesname value李四/propertyproperty nameage value12/propertyproperty namegender value男/propertyproperty namehobbyarrayvalue唱歌/valuevalue打游戏/value/array/property/bean!-- student3学生--
bean idstudent3 classpoij.studentproperty namesid value3/propertyproperty namesname valuelisa/propertyproperty nameage value21/propertyproperty namegender value女/propertyproperty namehobbyarrayvalue弹钢琴/valuevalue跳舞/value/array/property/bean!-- clazz对象--在内部使用list标签将上述的3个学生添加到班级当中--
bean idclazz1 classpoij.clazzproperty namecid value111/propertyproperty namename value软件1班/propertyproperty namestudentslistref beanstudent1/refref beanstudent2/refref beanstudent3/ref/list/property
/bean输出如下所示
clazz{cid111, name软件1班, students[student{sid1, sname张三, age20, gender女, clazznull, hobby[吃饭, 睡觉]}, student{sid2, sname李四, age12, gender男, clazznull, hobby[唱歌, 打游戏]}, student{sid3, snamelisa, age21, gender女, clazznull, hobby[弹钢琴, 跳舞]}]}引用list集合的bean为集合类型的属性赋值
如果在IOC容器中存在一个list集合类型的bean那么我们是否可以直接通过ref来引用呢如下所示 上述这种方式是不对的 我们现在要创建的是一个list集合类型的bean最主要的是要往list集合中去存储数据但如果我们单独创建一个bean类型是ArrayList,我们能做的只是为当前这个类中的属性赋值而不能通过bean标签为当前的这个集合去存取数据
正确方法
我们去配置一个集合类型的bean但这需要使用util约束
添加前spring.xml文件中是没有该约束的 添加之后新增util约束 修改spring.xml文件中的内容
!-- student1 --
bean idstudent1 classpoij.studentproperty namesid value1/propertyproperty namesname value张三/propertyproperty nameage value20/propertyproperty namegender value女/propertyproperty namehobbyarrayvalue吃饭/valuevalue睡觉/value/array/property/bean!-- student2 --bean idstudent2 classpoij.studentproperty namesid value2/propertyproperty namesname value李四/propertyproperty nameage value12/propertyproperty namegender value男/propertyproperty namehobbyarrayvalue唱歌/valuevalue打游戏/value/array/property/bean!-- student3 --bean idstudent3 classpoij.studentproperty namesid value3/propertyproperty namesname valuelisa/propertyproperty nameage value21/propertyproperty namegender value女/propertyproperty namehobbyarrayvalue弹钢琴/valuevalue跳舞/value/array/property/bean!-- clazz对象--
bean idclazz1 classpoij.clazzproperty namecid value111/propertyproperty namename value软件1班/property!-- 引用list集合的bean--property namestudents ref studentsList/property
/bean!-- 配置一个集合类型的bean需要使用util约束--
util:list idstudentsListref beanstudent1/refref beanstudent2/refref beanstudent3/ref
/util:list输出如下所示
clazz{cid111, name软件1班, students[student{sid1, sname张三, age20, gender女, clazznull, hobby[吃饭, 睡觉]}, student{sid2, sname李四, age12, gender男, clazznull, hobby[唱歌, 打游戏]}, student{sid3, snamelisa, age21, gender女, clazznull, hobby[弹钢琴, 跳舞]}]}依赖注入之为map集合类型的属性赋值
创建新的teacher类
package poij;public class teacher {private Integer tid;private String name;public Integer getTid() {return tid;}public String getName() {return name;}public void setName(String name) {this.name name;}public void setTid(Integer tid) {this.tid tid;}public teacher() {}public teacher(Integer tid,String name) {this.tid tid;this.namename;}Overridepublic String toString() {return teacher{ tid tid , name name \ };}
}修改student
//将老师作为学生的一个属性添加进来
private MapString,teacher stringteacherMap;//为其设置set和get方法public MapString, teacher getStringteacherMap() {return stringteacherMap;}public void setStringteacherMap(MapString, teacher stringteacherMap) {this.stringteacherMap stringteacherMap;}//重写toString方法
Overridepublic String toString() {return student{ sid sid , sname sname \ , age age , gender gender \ , clazz clazz , hobby Arrays.toString(hobby) , stringteacherMap stringteacherMap };}方法1通过map标签进行设置
修改spring.xml文件
假设我们现在要给id为student3的bean对象的stringteachermap属性赋值如下所示我们需要使用map标签而不是utilmap,因为utilmap的功能类似于utillist它是用来配置一个类型为map的bean对象 由于map中的数据是以键值对的形式存取的那么如何设置键值对呢
在map标签中我们输入显示的结果有以下两种看到entry不知道大家是否会感到格外的熟悉因为这是我们在java中就已经接触过的它表示的是一个类型map中的键和值我们可以使用一个entry来表示map集合中的一个键值对 entry中可包含的参数有以下几种和我们上面学习的其他类型是一样的凡是带有-ref的则证明这个参数的类型是一个对象若仅仅是key和value则证明这个参数是字面量 修改spring.xml文件中的内容
!-- 为id为student3的bean对象的stringteachermap属性赋值--
bean idstudent3 classpoij.studentproperty namesid value3/propertyproperty namesname valuelisa/propertyproperty nameage value21/propertyproperty namegender value女/propertyproperty namehobbyarrayvalue弹钢琴/valuevalue跳舞/value/array/property!-- 在student中mapString,teacher--property namestringteacherMapmap !-- teacher则使用引用外部bean的方式--entry key1号老师 value-refteacher1/entryentry key2号老师 value-refteacher2/entry/map/property/bean!-- 创建类型为老师的bean对象--
!-- teacher1--
bean idteacher1 classpoij.teacherproperty nametid value10086/propertyproperty namename value大宝/property
/bean!-- teacher2--
bean idteacher2 classpoij.teacherproperty nametid value10010/propertyproperty namename value小宝/property
/bean方法2通过util:map进行设置
对spring.xml进行修改
!-- 创建了类型为老师的bean对象--
bean idteacher1 classpoij.teacherproperty nametid value10086/propertyproperty namename value大宝/property
/beanbean idteacher2 classpoij.teacherproperty nametid value10010/propertyproperty namename value小宝/property
/bean!-- 为id为student3的bean对象的stringteachermap属性赋值--
bean idstudent3 classpoij.studentproperty namesid value3/propertyproperty namesname valuelisa/propertyproperty nameage value21/propertyproperty namegender value女/propertyproperty namehobbyarrayvalue弹钢琴/valuevalue跳舞/value/array/property!-- 直接通过id值引用util:map对象--property namestringteacherMap refteacherMap/property
/bean!-- 创建utilmap对象--
util:map idteacherMapentry key1号老师 value-refteacher1/entryentry key2号老师 value-refteacher2/entry
/util:map无论上述那种方法输出均为如下所示
student{sid3, snamelisa, age21, gender女, clazznull, hobby[弹钢琴, 跳舞], stringteacherMap{1号老师teacher{tid10086, name大宝}, 2号老师teacher{tid10010, name小宝}}}依赖注入之为p命名空间
在spring.xml文件中创建新的bean对象
bean idstudent4 classpoij.student p:sid12 p:sname小白 p:stringteacherMap-refteacherMap/bean但我们使用上述这种p属性开头的方法需要注意一定要引入p。它必须有约束的支持才能够进行如下所示 使用p开头的这种方式我们会发现每个属性都有两个:一个是不带-ref后缀一个是带-ref后缀在前面的学习中我们就说过带-ref表示该属性的值是一个类而不带-ref的表示该属性的值是一个字面量,注意在选择的时候不要选择错误了 在测试类中获取id为student4的bean对象
student studentioc.getBean(student4, poij.student.class);
System.out.println(student);输出如下所示我们未赋值的属性是以null显示
student{sid12, sname小白, agenull, gendernull, clazznull, hobbynull, stringteacherMap{1号老师teacher{tid10086, name大宝}, 2号老师teacher{tid10010, name小宝}}}这种方式虽然可行但并不是常用的因此我们了解一下即可!