IOC 作用是控制反转, DI 叫做依赖注入(给属性赋值)
为属性赋值的方式: 1. 通 过构造器为属性赋值。 2. 通过 set 方法为属性赋值。
DI依赖注入
1.set方法为属性赋值
想要为属性赋值 应该通过 spring 容器来做。要想为属性赋值 必须要有 set 方法, 容器通过形参传递参数给实参 属性才能正确赋值
<bean id="person" class="domain.Person">
<property name="name" value="1606"></property></bean>
<property name="age" value="2"></property>
属性赋值的原理:
对象中的属性和<property name="name" >中的name属性的值并没有直接的关系。他们是通过set方法建立的链接。
如果没有set方法就会报以下错误:
其他类型的注入:
<bean id="person" class="com.liming.domain.Person">
<property name="name" value="1606"></property>
<property name="age" value="2"></property>
<property name="student" ref="student"></property>//对象注入
<property name="strings" >//字符串注入
<array>
<value>上单</value>
<value>打野</value>
<value>中单</value>
</array>
</property>
<property name="list" >//list注入
<list>
<value>ADC</value>
<value>miss</value>
<value>小智</value>
<ref bean="student"/>
</list>
</property>
<property name="set" >//set注入
<set>
<value>miss</value>
<value>miss</value>
<value>miss</value>
</set>
</property>
<property name="map" >//map注入
<map>
<!-- value="" -->
<entry key="1" value-ref="student"></entry>
<entry key="2" value="卑职"></entry>
</map>
</property>
<property name="pro" >//property注入
<props>
<prop key="一">AAA</prop>
<prop key="二">BBB</prop>
</props>
</property>
</bean>
package com.liming.domain;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Person {
private String name;
private int age;
private Student student;
private String[] strings;
private List list;
private Set set;
private Map map;
//应用场景比较多
private Properties pro;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setStudent(Student student) {
this.student = student;
}
public void setStrings(String[] strings) {
this.strings = strings;
}
public void setList(List list) {
this.list = list;
}
public void setSet(Set set) {
this.set = set;
}
public void setMap(Map map) {
this.map = map;
}
public void setPro(Properties pro) {
this.pro = pro;
}
public void init(){//
System.out.println("自定义的初始化方法");
}
public Person(){
System.out.println("我是一个无参构造的人");
}
public void add(){
System.out.println("添加一个用户");
}
public void destroy(){
System.out.println("自定义的销毁方法");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", student=" + student
+ ", strings=" + Arrays.toString(strings) + ", list=" + list
+ ", set=" + set + ", map=" + map + ", pro=" + pro + "]";
}
public Properties getPro() {
return pro;
}
public List getList() {
return list;
}
public Set getSet() {
return set;
}
public Map getMap() {
return map;
}
public Student getStudent() {
return student;
}
public String[] getStrings() {
return strings;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
下图是注入property是导包出错后的报错,应该导入util下的property包
2.构造器赋值:
1. 当 index 和 name属性 同时出现的时候必须保证参数的正确。<!-- 通过构造方法为属性赋值
属性的含义
index="0"参数的位置(从0开始) name="参数的名称" ref="引用Bean的ID" value="固定的值(认为写的)" type="参数的类型(一般不配spring容器自动转换了)"
-->
<bean id="student" class="com.liming.domain.Student">
<constructor-arg index="0" name="name" value="张三" ></constructor-arg>
<constructor-arg index="1" name="age" value="18" ></constructor-arg>
</bean>
2.
当使用
index
或 name
的时候也能成功进行赋值。但是使用name属性可能会有问题
原因在没有关联源码的时候。形式参数可能会变成arg的形式。导致name属性赋值失败,所有建议使用index进行赋值。
SpringIOC和DI的意义
传统的设计模式中为了实现MVC分层的设计模式需要编写大量的代码才能实现代码的分层。现在使用spring能简单实现我们的分层设计。实现了解偶。
spring容器他是一个轻量级的框架,一配置简单。实现松耦合。
spring中DI中的标签
parent标签
Jdbc和c3p0的区别:jdbc和数据库交互时获取一次连接后完成数据读写断开连接,再有数据读写时再创建与数据库的链接重复上面操作;c3p0中有数据库连接池,它会提前向数据库申请链接放到数据库连接池中,有数据读写时,从池中获取一个链接,操作完成后将链接还回池中,这样避免了链接的频繁创建消耗计算机性能。
在每一个 DAO 中都需要数据源,如果没有简化的配置,就需要重复的进行配置!这样的做法并不好。<bean id="personDao" class="com.liming.dao.PersonDaoImpl" parent="baseDao" autowire="byName">
<!-- <property name="person" ref="person" ></property> -->
<!-- <property name="dataScource" ref="dataScource"></property> -->
</bean>
如果不加parent标签会报错。原因:因为spring容器在创建对象的时候并不知道你需要维护子父级关系。所以需要人为使用parent属性指明子父级关系。这样spring容器在创建对象的时候就能顺利维护关系。
abstract标签
abstract="true"这样配置该bean就不会创建对象,如下图
autowire标签
作用简化xml配置使用了autowire就不需要使用
<!-- <propertyname="person" ref="person"></property> -->
作用范围:引用类型的赋值
用法:
autowire="byName" 是通过属性的名称和bean的ID进行匹配的。
autowire="byName"===>setPerson()根据标签中有byName来找该类中的所有set方法=====>person属性(将setPerson中set去掉吧P大写改为p)=====>到配置文件的bean中查找对应的ID 找到则进行赋值如果不匹配则为null
autowire="byType" 通过类型进行匹配
autowire="byType"===>setPerson()=====>person属性=====>Person的Class形式=====>匹配配置文件里bean中的Class
代码spring02-4属性注解的使用的步骤
1、导入相关的头文件
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
</beans>
以上红色的是相比以前头文件改变的地方
以上蓝字为修改复制内容的地方(需要修改5个地方)
2、开启属性注解
<!--开启属性注解 -->
<context:annotation-config/>
3、使用注解
1、@Value(value="1606") 给基本类型和String进行赋值
2、@Autowired 给引用进行赋值
private Studentstudent;
4、注入原理
@Autowired 会根据你的属性的名称找到对应bean的ID,如果正确匹配则进行注入。当bean的ID不能匹配则会匹配它的类型(class)如果匹配成功则进行注入。如果匹配不成功则报错

扩充如果想指定Bean的ID进行注入
@Autowired
@Qualifier("studentQQQ")
当两个注解一起使用的时,只能按照ID进行匹配,不会再更具class来判断了

@Resource
它的用法和@Autowired一模一样
@Resource(name="studentQQQ") 如果ID不匹配则报错
和
@Autowired
@Qualifier("studentQQQ")
private Studentstudent;
用法相同

类的注解步骤
1.开启类扫描
<!--类扫描
里边包含了属性注解
多个包之间用","号隔开 不要加空格
-->
<context:component-scanbase-package="domain"/>
2.类上添加注解
@Component
public classPerson
3.实现原理
首先通过类扫描器找到相应的包然后扫描所有包下的类
如果有@Component注解 就会为这个类创建对象。对象的id就是类名并且首字母小写。存入到MAP中供我们调用。
4.@Component(value="p")
如果使用了value="P"那么这个对象的id就是P
@Component(value="personDao")//面向接口的编程所以要加value属性
5.注解的分层
@Repository dao层
@Service service层
@Controller 前端控制层
6.懒加载注解、多例注解等见文档点击打开链接
引入外部文件
<!--动态的读取外部文件
读取配置文件把内容放到容器中
-->
<context:property-placeholderlocation="classpath:spring.properties"/>
@Value("${name}")
private Stringname;