文章目录
ioc(Inversion of Control)控制反转
ioc简介
是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
如果我们直接使用传统的javaweb来创建对象
这个时候这三个类的耦合度太高了,不适合后期修改和运营
而使用了ioc可以使我们的对象通过spring框架给我们创建,这样就可以减少耦合
ioc底层
第一步配置xml文件
<bean id="user" class="*.*.*.UserDao">
Class test(){
@Test
public void test1(){
String classValue = class属性值;
Class clazz = Class.forName(classValue);//2、通过反射的方式创建对象
return (UserDao)clazz.newInstance();
}
}
1、这里他先通过xml的解析,把“..*.UserDao”拿出来赋值给UserFactory的classValue属性
2、然后通过Class.forName(classValue)方法通过反射找到他的class字节文件
3、再把这个类返回给clazz
4、最后返回这个类的实例。
ioc接口(beanfacory)
Spring提供了IOC容器实现的两种方式:
1、BeanFactory:IOC容器基本实现,是Spring内部使用的接口,不提供开发人员使用
2、ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员使用
区别:
使用BeanFactory的话,在加载配置文件的时候不会创建对象,在获取对象的使用才创建;
使用ApplicationContext的话,在加载配置文件的时候就会创建配置文件中的对象。
(只需要知道第一个是spring内部使用的,第二个才是平时开发的时候使用的)
public class testdemo {
@Test
public void testService(){
//通过ApplicationContext创建ioc容器
ApplicationContext context = new AnnotationConfigApplicationContext("applicationContext.xml");
//这个时候通过beanfactory创建对象
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
}
IOC操作Bean管理(基于XML)
Bean管理包括以下两个:
(1)Spring创建对象
(2)Spring注入属性(分为setter注入和有参构造注入)
无参创建对象
<bean id="user" class="com.jin.spring.User">
标识符 | Value |
---|---|
bean | 表示的是这个是个bean容器 |
id | 唯一表示bean容器的id |
class | 表示的所要的类的路径 |
set方法注入
首先创建User类
class User{
private String username;
public void setUsername(String username){
this.username = username;
}
public void show(){
System.out.println(username);
}
}
创建xml文件并写入
<bean id="user" class="com.jin.spring.User">
<property name="username" value="奥里给"></property>
</bean>
创建测试类
@Test
public void testService(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
user.add();
}
}
带参构造方法注入
首先创建User类
class User{
private String username;
public void User(String username){
this.username = username;
}
public void show(){
System.out.println(username);
}
}
这个时候xml文件就和set方法时候的有所不同
<bean id="user" class="com.jin.spring.User">
<constructor-arg name="username" value="奥里给"></constructor-arg>
</bean>
再调用test方法来测试
注入内部bean
创建UserDao
package com.example.spring5_demo.dao;
import org.springframework.stereotype.Service;
public interface UserDao {
public void add();
}
创建UserService类
package com.example.spring5_demo.service;
import com.example.spring5_demo.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
//@Component(value = "userService")
//@Service
public class UserService {
//
// @Autowired
// @Qualifier(value = "userDaoImpl1")
// @Resource(name = "userDaoImpl1")
private UserDao userDao;
public void add(){
System.out.println("service add.... ");
userDao.add();
}
}
创建UserDaoImpl类继承UserDao
package com.example.spring5_demo.dao;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.xml.bind.SchemaOutputResolver;
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("dao add...");
}
}
<!--这里class要指定Dao的实现类-->
<bean id="userDaoImpl" class="com.example.spring5_demo.dao.UserDaoImpl;"></bean>
<bean id="userService" class="com.example.spring5_demo.service.UserService">
<!--bean的注入,使用ref指定 你想要的bean的id-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
创建测试方法
@Test
public void testService(){
ApplicationContext context = new ClassPathXmlApplicationContext(SpringConfig.class);
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
注入外部bean
首先创建Emp类
package com.example.ioc.bean;
public class Emp {
private String ename;
private String gender;
//员工属于某一个部门,使用对象表示
private Dept dept;
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public void add(){
System.out.println(ename+"::"+gender+"::"+dept);
}
}
再创建Dept类
package com.example.ioc.bean;
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
@Override
public String toString() {
return "Dept{" +
"dname='" + dname + '\'' +
'}';
}
}
再xml文件中加入(做内部注入的配置)
<bean id="emp" class="com.example.ioc.bean.Emp">
<property name="ename" value="lucky"></property>
<property name="gender" value="男"></property>
<property name="dept">
<bean id="dept" class="com.example.ioc.bean.Dept">
<property name="dname" value="开发部"></property>
</bean></property>
</bean>
创建配置方法
@Test
public void testbean2(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Emp emp = context.getBean("emp",Emp.class);
emp.add();
}
}
注入成功
连级赋值
还是使用上面的两个类,修改xml文件
<bean id="emp" class="com.example.ioc.bean.Emp">
<property name="ename" value="lucky"></property>
<property name="gender" value="男"></property>
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="财务部"></property><!--这个直接使用了emp中的dept对象设置dept中的dname-->
</bean>
<bean id="dept" class="com.example.ioc.bean.Dept">
<property name="dname" value="开发部"></property>
</bean>
最后的运行结果是这个