一、IOC创建对象的三种方式
1、使用无参构造器,也是默认的创建方式
2、使用有参构造器
1)第一种:下标赋值 : <constructor-arg index="0" value="zhangsan"/>
2)第二种:类型赋值: <constructor-arg type="java.lang.String" value="zhangsan"/> 不能处理两个参数类型一样的情况
3) 第三种:直接通过参数名赋值 <constructor-arg name="name" value="zhangsan"/>
3、利用工厂创建对象
静态工厂:工厂本身不需要创建对象;通过静态方法调用,对象=工厂类.工厂方法名();
使用方法:
class: 指定工厂全类名
factory-method: 指定工厂方法
constructor-arg: 可以为方法传参
<bean id="airPlane01" class="com.lxy.factory.AirPlaneStaticFactory" factory-method="getAirPlane">
<constructor-arg name="name" value="波音747"/>
</bean>
实例工厂:工厂本身需要创建对象
工厂类 工厂对象 = new 工厂类();
工厂对象.工厂方法名();
区别就是 一个是静态的方法 一个不是 静态方法可以直接调用,不是静态需要先new
使用方法
1、先配置出实例工厂对象 <bean id="airPlaneInstaceFactory" class="com.lxy.factory.AirPlaneInstanceFactory"/>
2、配置我们要创建的AirPlane使用哪个工厂创建
1)、factory-bean指定使用哪个工厂创建
2)、factory-method指定使用哪个工厂方法
<bean id="airPlane02" class="com.lxy.pojo.AirPlane" factory-bean="airPlaneInstaceFactory" factory-method="getAirPlane">
<constructor-arg name="name" value="波音787"/>
</bean>
实现了FactoryBean的接口类是Spring可以认识的工厂类 自己写的工厂类需要继承FactoryBean
Spring会自动的调用工厂方法创建实例
1、编写一个FactoryBean的实现类
2、在Spring配置文件中进行注册
<bean id="myFactoryBeanImpl" class="com.lxy.factory.MyFactoryBeanImpl"/>
二、不同类型的赋值/注入方式
1、普通赋值
<bean id="hello" class="com.lxy.pojo.Hello">
<property name="str" value="Spring"/> 通过value
</bean>
2、对象赋值
<bean id="userServiceImpl" class="com.lxy.service.UserServiceImpl">
<property name="userDao" ref="mysqlImpl"/> 通过ref
<bean/>
3、bean注入 (以下<bean id=""><bean>等省略,只写了注入方式)
<property name="address" ref="hello"/>
4、数组注入
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>三国演义</value>
<value>水浒传</value>
</array>
</property>
5、list 注入(set同理 只是把标签换成<set>)
1) list中添加普通值
<property name="hobbies">
<list>
<value>敲代码</value>
<value>听音乐</value>
<value>打台球</value>
</list>
</property>
2) list中添加对象 (所有其他容器类型都可以通过这种方式进行对象添加)
<property name="bookList">
<list>
<bean id="book01" class="com.lxy.pojo.Book" p:bookName="三体"/>
<ref bean="book01"/>
</list>
</property>
6、map注入
1)不可引用注入
<property name="card">
<map>
<entry key="1" value="身份证"/>
<entry key="2" value="校园卡"/>
<entry key="3" value="医保卡"/>
</map>
</property>
2)可以引用注入(list、set也可以通过这种方式进行可以引用注入)
<util:map id="map">
<entry key="1" value="元素1"/>
<entry key="2" value="元素2"/>
<entry key="3" value="元素3"/>
</util:map>
7、null注入(主要用在想把某个已经赋值的属性再赋值为null)
<property name="wife">
<null/>
</property>
8、properties注入
<property name="info">
<props>
<prop key="学号">1111</prop>
<prop key="姓名">张三</prop>
</props>
</property>
9、继承<bean>的配置信息(如果一个<bean>设置有abstract=true 那么这个bean只能被继承,不能实例化)
<bean id="book02" class="com.lxy.pojo.Book" parent="book01" >
<property name="price" value="100"/>
</bean>
三、通过命名空间注入值 (c命名空间和p命名空间不能直接使用,需要导入xml约束)
1)、p命名空间注入,可以直接注入属性的值: property
singleton: 单例模式(spring默认机制)
1、在容器启动完成之前就已经创建好对象,保存在容器中
2、任何获取都是获取之前创建好的对象
导入p命名空间 xmlns:p="http://www.springframework.org/schema/p"
bean id="user" class="com.lxy.pojo.User" p:name="张三" p:age="24" scope="singleton"
2)、c命名空间注入,通过构造器注入: constructor-args
prototype: 原型模式:每次从容器中get的时候,都会产生一个新的对象
1、容器启动默认不会去创建多实例bean
2、获取的时候创建bean
3、每次获取都会创建一个新的实例对象
导入p命名空间 xmlns:p="http://www.springframework.org/schema/c"
<bean id="user2" class="com.lxy.pojo.User" c:age="24" c:name="李四" scope="prototype"/>
四、通过SpEL(Spring Expression Language)赋值
<bean id="student" class="com.lxy.pojo.Student">
<property name="name" value="lisi"/>
</bean>
<bean id="book" class="com.lxy.pojo.Book">
<property name="bookName" value="三体"/>
<property name="price" value="100"/>
</bean>
<bean id="user" class="com.lxy.pojo.User">
<!--字面量 #{} 可以在#{}里面直接写运算表达式-->
<property name="salary" value="#{12345.97*12}"/>
<!--引用其他bean的某个属性值-->
<property name="studentName" value="#{student.name}" />
<!--引用其他bean-->
<property name="book" value="#{book}"/>
<!--调用静态方法--> #{T(全类名).方法名}
<property name="id" value="#{T(java.util.UUID).randomUUID().toString().substring(0,5)}"/>
<!--调用非静态方法-->
<property name="age" value="#{book.getPrice()}"/>
</bean>
五、自动装配
自动装配:仅限于对自定义类型的属性有效 前提是容器中必须有相对应的组件
byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id 注意:不能够区分大小写,id都用小写
byType: 会自动在容器上下文中查找,和自己对象属相同的bean (可以省略id)注意:需要保证类型全局唯一
constructor: 按照有参构造器进行赋值
1、先按照有参构造器参数的类型进行装配,没有装配null
2、如果找到的类型有多个,参数的名作为id继续匹配
如果属性是一个容器 例如list<book> 那么自动装配会把所有的book的bean装配进去
<bean id="people" class="com.lxy.pojo.People" autowire="byName">
<property name="name" value="张三"/>
</bean>
也可以通过注解的方式 在属性上添加@Autowired
总之,自动装配的前提是spring容器中有对应的组件,才会把该组件的值装配/赋值到要自动装配的属性上去。没有就不赋值