spring 控制反转(IOC)与依赖注入( DI )

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38361347/article/details/82958400

1 什么是控制反转(ioc)?

ioc 是spring 最重要的一个思想,控制反转

我们以前自己通过自己new出来对象,我们 是执行人 ,我们有权利。

控制反转就是反过来容器帮我创建对象这一过程,把创建对象的权利交给容器,需要对象我们就管容器拿。

  • 没有ioc之前我们是怎么做的?

在servrlet学习中,我们都是在serviceimpl 和 daoimpl 中  new 出来dao 的对象  ,再通过dao的对象去调用数据库操作数据库,

serviceimpl 中 new dao的实现类,去调用dao层获取数据

最后在controller中 new  service 实现类 获取展示的数据以及传递数据给页面展示

 这样子做好像 感觉没什么问题?

实际上我们刚接触,刚开始学习可能感觉没什么,原因是自己没有接触过大的项目,而且很复杂的业务,我们刚刚开始无非就是一些增删改查而已,并不会觉得这种代码的扩展性,根本不会去考虑这些问题!

等到我们接触项目的时候用这种方式

一个业务类中不可能是1个,2个,3个那样子的dao层获取数据吧,通常都是3个以上了,各种处理数据,代码与代码直接的耦合度很高,业务层很难理解,代码也会很难写,好不容易写好的代码说改就改了,很常见!

这种耦合度很高的业务代码,很难扩展,导致自己的工作量变大,甚至加班...

所以我们经常听一些人,老师老是说 面向接口编程 就是这个道理,为了扩展性,为了降低耦合度。

为了解决对象间耦合度过高的问题,所以就有了 IOC 理论,用来实现对象之间的“解耦”。

控制反转(Inversion of Control)是一种是面向对象编程中的一种设计原则,用来降低计算机代码之间的耦合度。

其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦。

2 为什么要用spring ioc ?

为了解耦合,为了我们之后写代码,能方便进行扩展,也是为了我们少些代码,少折腾,节省时间,我觉得这才是最重要!

3 ioc和 di 有什么关系?

ioc 是控制反转

di 是依赖注入

比如:UserController类中 我们需要用到 UseSercvice 这个类, UserController对这个UseSercvice类存在依赖。

需要用到这个依赖,我们就必须去new这个对象,然后去一系列操作,但是这样子耦合度又变高了。

所以这时候我们需要spring容器帮我们去创建这个UseSercvice 对象,利用这个UseSercvice 对象引用,依赖这个对象的引用。

ioc 和di 关系  被注入对象依赖IoC容器配置依赖对象 

请参考大师级人物Martin Fowler的一篇经典文章《Inversion of Control Containers and the Dependency Injection pattern》,原文地址:http://www.martinfowler.com/articles/injection.html。

4 配置以及使用

  新建maven工程 然后引用依赖

  • 项目结构

  • Maven依赖

 <dependencies>
        <!-- spring的依赖包 -->
        
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.1.RELEASE</version>
            <type>jar</type>
        </dependency>
        
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        
        <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${org.springframework.version}</version>
        </dependency>
        
        </dependencies>

  • user类
package com.udeam.user;

import java.util.List;
import java.util.Map;

public class User {

	private  Long id;
	private String name;
	
	private Stu stu;
	
	private List<String> list;
	
	private List<Stu> listStu;
	
	private Map<String,Stu>  map;
	
	public User(Long id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	
	
	public User() {
		super();
	}


	public List<String> getList() {
		return list;
	}


	public void setList(List<String> list) {
		this.list = list;
	}


	public List<Stu> getListStu() {
		return listStu;
	}


	public void setListStu(List<Stu> listStu) {
		this.listStu = listStu;
	}


	public Map<String, Stu> getMap() {
		return map;
	}


	public void setMap(Map<String, Stu> map) {
		this.map = map;
	}


	public Stu getStu() {
		return stu;
	}


	public void setStu(Stu stu) {
		this.stu = stu;
	}


	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}


	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", stu=" + stu + ", list=" + list + ", listStu=" + listStu
				+ ", map=" + map + "]";
	}
	
}
  • stu类
package com.udeam.user;

public class Stu {

	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
	
}
  • service类

public interface UseSercvice {

	
	public void say();
}
  • service实现类
package com.udeam.Service;

import org.springframework.stereotype.Service;

@Service
public class UseSercviceImpl  implements UseSercvice{

	public void say() {
		 
		System.out.println("hahhaha...");
		
	}

}
  • controller 类
package com.udeam.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.udeam.Service.UseSercvice;

@Controller	
public class UserController {

	@Autowired
	private 	UseSercvice useSercvice;
	
	public UseSercvice getUseSercvice() {
		return useSercvice;
	}

	public void setUseSercvice(UseSercvice useSercvice) {
		this.useSercvice = useSercvice;
	}

 
}
  • spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"      
	xmlns:mvc="http://www.springframework.org/schema/mvc"   
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	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.xsd  
            http://www.springframework.org/schema/context   
            http://www.springframework.org/schema/context/spring-context.xsd  
            http://www.springframework.org/schema/mvc  
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd "
	default-autowire="byName">
	
	
	<!-- 注解扫描 -->
	<context:component-scan base-package="com.udeam.**"></context:component-scan>
	
	
	<!--注入的三种方式  -->
	
	<!-- 1 get set注入  -->
	<bean id="user" class="com.udeam.user.User" />
	<!-- 通过属性设置值 -->
	<bean id="user1" class="com.udeam.user.User">
			<property name="id" value="1" />
			<property name="name" value="zs" />
	</bean>
	
	<!-- 2  通过构造方法 通过构造方法设置值 -->
	<bean id="user2" class="com.udeam.user.User">
		 		<constructor-arg type="Long" value="2"  />
		 		 <constructor-arg type="String" value="zs2" />
	</bean>
	
	
	<bean id="stu" class="com.udeam.user.Stu">
			<property name="id" value="1" />
			<property name="name" value="stu1" />
	</bean>
	
	<!-- 3 复杂对象的注入 -->
	
	<!-- 对象里面含对象 -->
	<bean id="user3" class="com.udeam.user.User" >
			<property name="id" value="1" />
			<property name="name" value="name" />
			
			<!-- 引用是上面stu的注入方法 --> 
			<property name="stu" ref="stu" />
	
	</bean>
	
	
		<!-- list -->
	<bean id="stringList" class="com.udeam.user.User" >
			<property name="id" value="1" />
			<property name="name" value="name" />
			
			<!-- 引用是上面stu的注入方法 --> 
			<property name="list">
			
			<list> 
				<value> 1</value>
				<value> 2</value>
			 	<value> 3</value> 
			  	<value> 4</value> 
			</list>
			 
			</property>
	
	</bean>
	
		<!-- list里面存储stu对象 -->
		<bean id="userList" class="com.udeam.user.User" >
			<property name="id" value="1" />
			<property name="name" value="name" />
			
			<!-- listStu的注入方法 --> 
			<property name="listStu">
			
			<list> 
						<ref bean="stu"/>
			</list>
			 
			</property>
	
	</bean>
	
	
		<!-- map -->
	<bean id="mapUser" class="com.udeam.user.User" >
			<property name="id" value="1" />
			<property name="name" value="name" />
			
			<!-- 引用是上面stu的注入方法 --> 
			<property name="map">
			
			<map>
				<entry key="1"   value-ref="stu"> </entry>
				<entry key="2"   value-ref="stu"> </entry>
			</map>
			</property>
	
	</bean>
	
	
</beans>

通过xml 配置这种方式实际开发中能用来配置 一些数据库,aop等,实际类中用不到(由于项目类很多,这样子给自己增加工作量)

一般我们会采用注解注入的方式一般我们会采用注解注入的方式

  • 测试类

package udeam.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.udeam.Service.UseSercvice;
import com.udeam.controller.UserController;
import com.udeam.user.User;

public class test {

	public static void main(String[] args) {

		//加载springContext 配置文件
		
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
		User user = (User) context.getBean("user");
		//属性注入
		User user1 = (User) context.getBean("user1");
		///通过构造方法 
		User user2 = (User) context.getBean("user2");
		//复杂对象的注入
		User user3 = (User) context.getBean("user3");
		System.out.println(user);
		System.out.println(user1);
		System.out.println(user2);
		System.out.println(user3);
		
		//list中存放stu对象
		User userList = (User) context.getBean("userList");
		System.out.println(userList);
		
		//list中存放String
		User stringList = (User) context.getBean("stringList");
		System.out.println(stringList);
		
		//Map中存放string,stu
		User mapUser = (User) context.getBean("mapUser");
		System.out.println(mapUser);
		
		
		//通过注解注入,获取controller 对象 ,自动注入并且获取services 
		UserController userControlller = context.getBean(UserController.class);
		UseSercvice c = userControlller.getUseSercvice();
		c.say();
		
	}

}

常用的注解

@Service  表示声明当前类是一个service类

@Autowired 自动装配,自动注入依赖

@Controller 声明为控制类

注解扫描 
    <context:component-scan base-package="com.udeam.**"></context:component-scan>

一个*表示当前层下一层的目录,2个表示当前目录的不止一层包 ,也就是所有层包的目录

猜你喜欢

转载自blog.csdn.net/weixin_38361347/article/details/82958400