Spring学习
IOC---控制反转(反转控制)
IOC是Java把创建和调用对象的工作交给Spring容器来进行处理,目的是为了降低耦合度
底层
底层有三部分xml文件解析、工厂模式、反射( 获取Java的字节码文件【即Java编译后的 .class文件】,得到其中的方法和变量进行调用 )
工厂模式---就是建立一个类做工厂,然后将想要创建的类的对象都在里面实现使用只要调用这个工厂类的方法就行了,但是耦合度还是很高
IOC过程
1、创建xml配置文件,在配置文件时将想要创建、调用的类都装进去
2、创建一个工厂类,在里面解析xml文件,通过反射创建对象,得到文件的编码文件
String classValue = 解析配置文件 Class cls = Class.forName(classValue)
3、创建类的实例对象并返回该值
return (类型转换)cls.newInstance();
IOC思想和功能实现接口
IOC思想基于IOC容器,IOC底层实际就是对象工厂
IOC提供了两个接口用来实现IOC容器
1)BeanFactory,是Spring自带的接口,他只会在类需要被用到时才会创建对象,不然就不会创建对象,不推荐在开发时使用
2)ApplicationContext,BeanFactory的子接口是一个功能更加强大的接口,也能够解析获取xml文件中的类,并创建对象不管需不需要调用。平时开发时使用,因为Spring经常会跟Web项目一起进行工作,需要在服务器启动时就完成各项消耗资源的工作
3)ApplicationFactory接口有两个实现类ClassPathXmlApplicationContext和FileSystemXmlApplicationContext
ClassPathXmlApplicationContext实现类解析xml文件是在src目录下需要使用时
FileSystemXmlApplicationContext实现类使用时需要写上xml文件在磁盘上的准确目录:D:\hi\hello...
Bean管理操作有两种方式
1)基于xml文件管理
2)基于注解管理
IOC管理xml方式创建对象和注入属性
<1>配置对象创建
<bean id="add" class="xlw.com.test.Add"></bean>
通过bean标签添加对应的属性值是实现对象的创建,bean中有两个属性值需要注意id 和 name
id是具有唯一性,用于区别创建的对象,里面的值不能添加符号别的。
name可以在里面添加特殊符号,这个属性本来是提供给status1使用的,但是因为技术原因不再使用这个技术
class属性是用来指明想要创建对象的类,类全路径
在创建对象时通过调用无参构造方法创建类的对象,当创建了有参构造方法后,也要创建无参构造方法
A <2>注入属性 DI(依赖注入、属性注入) set方法
创建类和方法、变量
public class ToBean { public String name; public String author; public void setName(String name) { this.name = name; } public void setAuthor(String author) { this.author = author; } public void store(){ System.out.println(name+"--"+author); } }
在xml文件 中使用bean标签实现对象创建
其中注入属性就是字在bean标签对中通过property标签进行注入属性
在property边里有name 、value属性对应起来进行注入属性
<bean id="toBean" class="xlw.com.test.ToBean"> <property name="name" value="九阴白骨爪"></property> <property name="author" value="殷素素"></property> </bean>
<3>解析xml文件
@Test public void toBean(){ //解析xml文件 ApplicationContext application = new ClassPathXmlApplicationContext("hi.xml"); //获取对象 ToBean toBean = application.getBean("toBean", ToBean.class); toBean.store(); }
<4>获取想要调用的类对象
<5>使用对象
P 名称空间(实际使用名称空间实现) 注入
1、首先对xml文件beans标签中的内容进行修改,添加 xmls:p 实现添加名称空间
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
2、使用
<bean id="toBean" class="xlw.com.test.ToBean" p:name="降龙十八掌" p:author="洪七公"> </bean>
在bean标签中使用 p名称空间,输入后就能发现可以对class指向的类中的变量进行赋值(属性注入),这个方法适用于set方法注入属性(简化代码)
B 注入属性 DI 有参构造方法
<bean id="toBean" class="xlw.com.test.ToBean"> <constructor-arg name="name" value="冰魄银针"></constructor-arg> <constructor-arg name="author" value="你好"></constructor-arg> </bean>
在通过有参构造方法进行实现属性注入时,使用constructor-arg标签实现,跟property差不多
其中也有index、value通过索引参数实现属性注入
调用一样
@Test public void toBean(){ ApplicationContext application = new ClassPathXmlApplicationContext("hi.xml"); ToBean toBean = application.getBean("toBean", ToBean.class); toBean.store(); }
IOC操作Bean,xml注入其他类型属性
字面量:就是在类中定义的变量被直接赋值,或者在xml文件中对通过属性注入(name=value)方式赋值,设置使用固定值就是字面量。
设置null值
<bean id="toBean" class="xlw.com.test.ToBean"> <property name="name" value="九阴白骨爪"></property> <property name="author"> <null/> </property> </bean>
设置特殊符号使用转义符或CDATA
<value>标签中的所有内容都是值
<bean id="toBean" class="xlw.com.test.ToBean"> <property name="name" value="九阴白骨爪"></property> <property name="author"> <value> <![CDATA[ 特殊符号 ]]> </value> </property> </bean>
IOC管理---外部Bean
外部Bean注入就是在实际开发中,会分很多层,上层调用下层方法时要通过实例化对象实现,而现在来说就是通过外部Bean注入。
在AddUser中
public class AddUser { // 将类对象做为类内部属性,通过set方法实现属性注入 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void addUser(){ userDao.addUser(); } }
在xml文件里
首先创建上层类(AddUser)对象,由于使用了set方法进行属性注入,所以采用property标签以name=ref的方式进行注入,因为类中的属性是一个类对象,所以不能用value,要用ref
其次要注意的是创建UerDao的对象,由于并没有在service层中的类AddUser中实例化它,在使用中要使用到他的方法,创建它的对象时,使用bean标签,class要指向它的实现类,id值与 注入的属性值(ref)一致
// 创建属性的对象时,属性的id值与注入属性的值(ref)一致 <bean id="userDaoImpl" class="xlw.com.dao.Impl.UserImpl"></bean> <bean id="addUser" class="xlw.com.service.AddUser"> <property name="userDao" ref="userDaoImpl"></property> </bean>
这就叫外部Bean注入
IOC管理---内部Bean和级联赋值
内部bean的属性注入
bean类中
里面有另一个类( Student )作为内部属性
public class Student { private String stuName; private String hobby; private School school; public void setSchool(School school) { this.school = school; } public void setStuName(String stuName) { this.stuName = stuName; } public void setHobby(String hobby) { this.hobby = hobby; } }
xml文件中
在xml文件中对bean类进行属性注入,由于student中有一个类对象做属性,所以就可以在属性注入时采取 内部bean注入,即在property标签中嵌套<bean>标签,再在bean标签中嵌套<property>标签实现属性注入。这就叫 内部bean注入
<bean id="student" class="xlw.com.bean.Student"> <property name="stuName" value="马牛逼"></property> <property name="hobby" value="乱入尴尬"></property> <property name="school"> <bean id="school111dasda" class="xlw.com.bean.School"> <property name="name" value="牛逼学校"></property> </bean> </property> </bean
第二种 外部bean注入
外部注入就是在进行注入属性时,使用property标签以name=ref进行注入,将对象类中的实体对象属性在外面重新用bean标签创建对象并用property注入属性,再用ref获取创建对象的id实现属性注入
这里注意 ref的值是要等与外部bean创建对象的id值,不是id值等于ref值
<bean id="student" class="xlw.com.bean.Student"> <property name="stuName" value="摇摆阳"></property> <property name="hobby" value="摇摆"></property> <property name="school" ref="schoolijiojll"></property> </bean> <bean id="schoolijiojll" class="xlw.com.bean.School"> <property name="name" value="gun!"></property> </bean>
第三种 级联赋值
级联赋值是在外面创建bean对象,在内部通过property标签以name=value的方式进行属性注入,用 .运算符取到内部实体类属性的属性并赋值
这种 外部bean属性注入要注意,该对象的类中要有这个实体类属性的get方法,在进行属性注入 之前要先以name=ref给内部实体类属性进行属性注入。并且,我发现对同一个属性进行注入,这种方式的优先级大于外部bean标签内注入属性
<bean id="student" class="xlw.com.bean.Student"> <property name="stuName" value="渣渣辉"></property> <property name="hobby" value="认兄弟来砍我"></property> <property name="school" ref="school"></property> <property name="school.name" value="贪玩蓝月"></property> </bean> <bean id="school" class="xlw.com.bean.School"> <property name="name" value="dhaskjdhkasj" ></property> </bean>
IOC管理---对集合类型的属性进行属性注入
在bean类中
public class Collection { private String[] arrayList; private List list; private Map<String,String> map; private Set<String> set; public void setArrayList(String[] arrayList) { this.arrayList = arrayList; } public void setList(List list) { this.list = list; } public void setMap(Map<String, String> map) { this.map = map; } public void setSet(Set<String> set) { this.set = set; } @Override public String toString() { return "Collection{" + "arrayList=" + Arrays.toString(arrayList) + ", list=" + list + ", map=" + map + ", set=" + set + '}'; } }
在xml文件中
在对集合类属性进行属性注入时,在property标签中使用对应类型的标签对,在标签对内部通过value标签对list进行属性注入多个值。当然还是一个属性一个property标签
注意:map属性进行属性注入时使用entry标签,并在标签里面通过key=value的方式注入,通过多个entry标签实现注入多个值
<bean id="collection" class="xlw.com.bean.Collection"> <property name="arrayList"> <array> <value>心态</value> <value>身体</value> <value>学习</value> </array> </property> <property name="list"> <list> <value>快乐</value> <value>健康</value> <value>循序渐进</value> </list> </property> <property name="map"> <map> <entry key="1"