IOC[ Inversion of controller ] 控制反转
DI [Dependency Injection] 依赖注入
IOC 能够做的事情 由程序员主动通过 new 实例化对象事情转交给 Spring 负责 ,控制反转中反转指的是转交给 Spring 负责
DI 当一个类(A)中需要依赖另一个类(B)对象时,把 B 赋值给 A 的过 程就叫做依赖注入
Spring 环境搭建 四个核心包以及loggin日志包
新建spring配置文件 applicationContext.xml 【文件名和路径可以自定义】
该文件中配置的对象最终被加载到了ApplicationContext容器中
说明:Spring配置文件是基于schema 该schema 文件扩展名为 xsd,把 schema 理解成 DTD 的升级版,比 DTD 具备更好的扩展性,每次引入一个 xsd 文件是一个 namespace(xmlns)
配置文件中只需要引入基本 schema 通过bean标签 创建对象 该配置文件被加载时创建对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd
">
<!-- id 表示获取到对象标识
class 创建哪个类的对象
-->
<bean id="user" class="com.xt.a_create.Users"></bean>
</beans>
测试代码
public static void main(String[] args) {
//实例化SpringIOC容器 加载spring配置文件 第二个参数是读取当前类同包下的配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml",Test.class);
getBean("<bean>标签 id 值",返回值类型);如果没有第二个参数, 默认是 Object
Users user = ac.getBean("user", Users.class);
System.out.println( user );
//getBeanDefinitionNames(),Spring 容器中目前所有管理的所有
String[] beanNames = ac.getBeanDefinitionNames();
for (int i = 0; i < beanNames.length; i++) {
System.out.println( beanNames[i]);
}
}
创建对象的多种方式
通过构造方法创建
1 无参构造创建:默认情况.
2 有参构造创建:需要明确配置
2.1 需要在类中提供有参构造方法
2.2 在 applicationContext.xml 中设置调用哪个构造方法创建 对象
index : 参数的索引,从 0 开始
name: 参数名
type:类型(区分开关键字和封装类 int 和 Integer)
<!-- 指定构造方法创建对象 -->
<bean id="user" class="com.xt.a_create.Users">
<constructor-arg name="userId" value="10" type="int"></constructor-arg>
<!-- <constructor-arg name="userName" value="张三" type="java.lang.String"></constructor-arg> -->
<!-- ref 引入另外的bean value 基本数据类型或String 等 -->
<constructor-arg ref="nameValue"></constructor-arg>
</bean>
<!-- 创建 String 的实例对象 -->
<bean id="nameValue" class="java.lang.String">
<constructor-arg index="0" value="李四"></constructor-arg>
</bean>
实例工厂
1 工厂设计模式:帮助创建类对象.一个工厂可以生产多个对象.
2 实例工厂:需要先创建工厂,才能生产对象
必须要有一个实例工厂
public class UserFactory {
//工厂方法
public Users getUserInstance(){
return new Users();
}
//静态方法
public static Users getUsersInstances(){
return new Users();
}
}
在 applicationContext.xml 中配置工厂对象和需要创建的 对象
<!-- 配置 工厂类 -->
<bean id="userFactory" class="com.xt.a_create.UserFactory"></bean>
<!-- 通过工厂类调用 工厂方法获取 对象 -->
<bean id="user" factory-bean="userFactory" factory-method="getUserInstance"></bean>
3.静态工厂 [不需要创建工厂,快速创建对象]
<bean id="getUsers" class="com.xt.entity.UserFactory" factory-method="getUsersInstances"></bean>
二:处理对象依赖关系[注入]
实体类
public class Users {
private int userId;
private String userName;
private Set<String> sets ;
private List<String> list;
private String [] arrs ;
private Map<String,Object> map ;
private Properties prop ;
public Properties getProp() {
return prop;
}
public void setProp(Properties prop) {
this.prop = prop;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public String[] getArrs() {
return arrs;
}
public void setArrs(String[] arrs) {
this.arrs = arrs;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Set<String> getSets() {
return sets;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public Users() {
System.out.println("无参构造");
}
public Users(int userId,String userName) {
super();
this.userId = userId;
this.userName = userName;
System.out.println("有参构造 id name ");
}
public Users(String userName,int userId) {
super();
this.userId = userId;
this.userName = userName;
System.out.println("有参构造 name id ");
}
@Override
public String toString() {
return "Users{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", sets=" + sets +
", list=" + list +
", arrs=" + Arrays.toString(arrs) +
",map= "+map+
",pro="+prop+
'}';
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
1.构造方法模式
<bean id="user" class="com.xt.a_create.Users">
<!--<property name="userId" value="100" ></property>
<property name="userName" value="张三"></property>-->
<!-- 等同于 -->
<property name="userName">
<value>张三</value>
</property>
<property name="userId">
<value>100</value>
</property>
</bean>
2.set方法注入值 [普通属性 集合属性(list,map,property)]
<!-- set集合 -->
<property name="sets">
<set>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</set>
</property>
<!-- list集合 -->
<property name="list">
<list>
<value>网吧</value>
<value>手机</value>
<value>电脑</value>
</list>
</property>
<!-- 数组-->
<property name="arrs">
<array>
<value>张</value>
<value>王</value>
<value>李</value>
</array>
</property>
<!-- map集合 -->
<property name="map">
<map>
<entry key="en" value="england"></entry>
<entry key="ch" value="china"></entry>
<entry key="jp" value="japan"></entry>
</map>
</property>
<!-- properties 类-->
<property name="prop">
<props>
<prop key="user" >root</prop>
<prop key="pwd" >123456</prop>
</props>
</property>
3.内部bean
<bean id="userService" class="com.xt.a_create.UserService">
<!-- 成员属性 对象类型 提供 set方法 -->
<property name="userDao">
<bean id="userDao" class="com.xt.a_create.UserDao"></bean>
</property>
</bean>
4.p名称空间
引入p名称空间
<bean id="userDao" class="com.xt.a_create.UserDao"></bean>
<!-- 通过 p:属性-ref 引入 一个 bean -->
<bean id="userService" class="com.xt.a_create.UserService" p:userDao-ref="userDao"></bean>
5.自动装配
<bean id="userDao" class="com.xt.a_create.UserDao"></bean>
<!-- autowire 自动装配
byName 根据名称自动装配,会在容器中找指定名称的对象,注入到set方法的参数中
byType 根据类型自动装配,要确保该类型对应的对象在IOC容器中 唯一,否则报错
-->
<bean id="userService" class="com.xt.a_create.UserService" autowire="byName"></bean>
注解方式
加入 context 命名空间
applicationContext.xml中开启注解
<!-- 开启注解 base-package 指定的包扫描注解-->
<context:component-scan base-package="com.xt.a_create"></context:component-scan>
@Component//加入到IOC容器 默认名称是该类的第一个字母小写,跟后续
public class UserService {
@Resource//会根据指定的名称去IOC容器中找对应的对象注入
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void save(){
userDao.save();
}
}
常用的注解
@Component 标识一个组件[类],把当前容器加入到IOC容器 名称默认类名第一个字母小写
@Component(name="") 指定加入IOC容器组件类的名称
@Repository 标识为一个持久层组件
@Service 标识为一个业务逻辑层组件
@Controller 标识为一个控制层组件 [web层]
@Resource
1.根据属性名称 会去IOC容器找对象自动注入,找到注入
2.如果名称没找到,再根据类型找 找到注入[如该类型多个,报错]
@Resource(name="") 根据指定的名称去容器中找
@Autowired 自动装配