Spring IOC(DI)原理

注:本文于个人观点,如有错误欢迎纠正

一 名词解析:

1.IOC是一种"控制反转"思想

以前在程序中需要创建对象时,都是我们自己手动去new出来,这样非常麻烦,不利于对象管理。况且代码讲究低耦合(耦合:就是单元代码的紧密程度,一个单元代码的改动对另一个单元代码的影响),于是采用ioc思想,将对象创建、维护、销毁的控制权利交个了spring容器。

2.DI是依赖注入,是IOC的一种重要实现

一个对象的创建可能涉及到另一个对象的创建,比如A对象的成员变量持有B对象的引用,这就是依赖,A依赖于B,那么spring容器在创建对象A的时候,也会创建对象B,并把对象B注入到对象A中。

二 案例讲解:

采用一个例子来讲解下它的原理:

1.先引入spring所需的jar包,如果是maven则直接在pom.xml配置,否则手动添加jar包

2.创建一个DAO层接口,比如UserDao:

public interface userDao{
  void addUser();
}

3.实现UserDao接口,生成UserDaoImpl:

public class UserDaoImpl implements UserDao{
    void addUser(){
        System.out.println("这是DAO层的具体实现-addUser方法的具体实现");
     }  
}

4.创建一个UserServicw接口,抽象方法do(),创建UserServiceImpl实现它:

public class UserServiceImpl implement UserService{
  //依赖注入的对象
    private UserDao userDao;
    
 public void setUserDao(UserDao userDao){
   this.userDao=userDao;
   }
 public void do(){
   System.out.println("业务层的具体实现")
   userDao.addUser();
   }
}

5.xml配置文件:spring-ico.xml

<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
        ">
    <!-- 声明userDao对象,交给spring创建 -->
    <!--声明bean名称时可以用name、id,id唯一,name可以有多个-->
    <bean name="userDao" class="com.yc.dao.impl.AccountDaoImpl"/>
    <!-- 声明userService对象,交给spring创建 -->
    <bean name="userService" class="com.yc.service.impl.AccountServiceImpl">
          <!-- 注入userDao对象,需要set方法 对象引用用ref,这就是依赖注入-->
          <property name="userDao" ref="userDao"/>
    </bean>
</beans>

6.测试:

@Test
public void testByXml() throws Exception {
    //加载配置文件
   ApplicationContext applicationContext=
newClassPathXmlApplicationContext("spring/spring-ioc.xml");
    UserService userService= (UserService) applicationContext.getBean("userService");
    userService.do();
}

7:运行结果:

业务层的具体实现
这是DAO层的具体实现-addUser方法的具体实现

8.分析:

  • 第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的classpathXmlApplicationContext API 去生成工厂 bean。ClasspathXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。

  • 第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean 名称 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。

三.Spring容器的依赖注入(基于xml配置和注解)

注入依赖有两种方式:一种是手动装配(分为两种:xml配置、注解(@Resource默认按名称注入;@AutoWired默认按类型,如果要按名称的话通常搭配@Qualifier)),另一种是自动装配(自动装配分三种:按名称、按类型、构造方法)

对象依赖注入的四种方法(xml配置):

1.set注入

<bean id="userDao"  class="com.yc.dao.Impl"></bean>
<bean id=userService"  class="com.yc.service.impl">
<!--实现类需要有依赖对象的参数的set方法-->
<property  name="userDao ref="userDao"/>
</bean>

2.构造方法注入

<bean   id="userDao"   class="com.yc.dao.impl"></bean>
<bean  id="userService" class="com.yc.service.impl">
<!--实现类需要有依赖对象的参数的构造方法-->
<!--constuctor节点有四个属性:index(当构造方法参数有两个以上,传值得时候index代表索引从0开始)、type(参数的类型)、ref(注入依赖对象)、value(值)-->
<constructor-arg   ref="userDao"/>
</bean>

3.静态工厂方法和实例工厂

 3.1 bean对象

class User{
private String name;
private int age;

public void setName(String name){
this.name=name;
   }
public void setAge(int age){
this.age=age;
   }
}

3.2 工厂类:

public  class Factory{
public static User add(){
  User user=new User();
  user.setName=("张三");
  user.setAge(18);
}

public User add2(){
  User user=new User();
  user.setName=("李四");
  user.setAge(20);
}
}

3.3 xml配置为:

<!-- 静态工厂创建,调用静态方法add-->
<bean id="user1" class="com.yc.Factory" 
  factory-method="add"/>

<!-- 工厂实例创建,先创建工厂类在调用方法add2-->
<bean id="factory" class="com.yc.Factory" />
<bean id="user2" factory-bean="factory"  factory-method="add2"/>

4 bean对象基于注解扫描

从上面知道,spring容器负责控制创建对象,我们要做的是在xml配置文件中申明需要创建的对象,但是当需要创建对象特别多的时候,可能会特别复杂。以此使用注解会非常方便:@Repository(申明DAO层的实现层)、@Service(申明业务层的实现层)、@Controller(控制层) 、@Component;最后需要我们在xml配置文件中加入包扫描,就是扫描这些注解所在的位置。

<!-- 声明包扫描 -->
<context:component-scan base-package="com.yc" /> 

 

猜你喜欢

转载自blog.csdn.net/qq_40693828/article/details/81094884