转载

Spring中依赖注入与容器

依赖注入、IoC/DI

Spring 框架(核心)IoC 容器

 IoC:控制反转
 DI:依赖注入

 什么是依赖?
一个组件(对象)的运行需要用到另一个组件(对象),称这种关系为依赖关系

 举例:鱼依赖水,生命依赖空气、阳光、水、食物


组件依赖的资源(其他组件)由所在环境(上下文、容器)传递进去

 依赖注入的几种形式

- 接口注入
- 构造器注入
- 属性(setter)注入

  容器

容器是管理 组件的生命周期,注入组件(声明)所需的资源

例如:

容器 : 国家  义务教育、纳税、社保、医疗、养老
组件 : 公民

- apache tomcat 是 JSP/Servlet 容器,管理的组件继承特定的父类或实现特定的接口

- jboss 是 EJB 容器,管理的组件继承特定的父类或实现特定的接口(侵入式)

- Spring 是 POJO 容器,是一个低侵入的容器,注解


@Component 注解:组件
组件的作用域 `@Scope` 有哪几种:

单例(默认),全局唯一(单例模式)

原型,每次获得一个新实例(工厂模式)

请求作用域:web 应用

会话作用域:web 应用

 作用域:组件存在(有效)的范围,生命周期。

Component

 Repository  仓库,数据访问(DAO,Mapper)
 Service     业务逻辑
 Controller  控制器

工程目录:(需要手动添加依赖)


 



 


AccountService .java

package com.newer.ioc2.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.newer.ioc2.repository.AccountRepository;
import com.newer.ioc2.repository.LoginRepository;

/**
 * 组件 / POJO:委托给容器管理
 * 
 * @author
 *
 */
@Service
public class AccountService {

	// 业务逻辑依赖数据访问
	// 依赖注入进来
	// 很方便的切换依赖的具体实现
	@Qualifier("mongodb")
	@Autowired
	AccountRepository accountRepository;
	
	@Autowired
	LoginRepository loginRepository;

	// 一个业务操作,往往包含多个数据操作
	
	// 创建
	public boolean create(String name, String password) {
		System.out.println("AccountService");
		
		accountRepository.create(name, password);
		
		return true;
	}
	
	// 登录
	
	// 注销
	
	// 更新信息
	
	// 锁定
	
}

 OrderSevice.java

package com.newer.ioc2.service;

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

import com.newer.ioc2.repository.AccountRepository;
import com.newer.ioc2.repository.OrderRepository;
import com.newer.ioc2.repository.ProductRepository;

/**
 * @Service 是封装了业务逻辑的组件
 * 
 * @author 
 *
 */
@Service
public class OrderService {

	@Autowired
	AccountRepository accountRepository;
	
	@Autowired
	ProductRepository productRepository;
	
	@Autowired
	OrderRepository orderRepository;
	
	// 一个业务逻辑往往会包含多个数据操作,依赖多个数据操作
	
	
}

 Ioc2Application.java

package com.newer.ioc2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Ioc2Application {

	public static void main(String[] args) {
		SpringApplication.run(Ioc2Application.class, args);
	}

}

ProductRepository.java

package com.newer.ioc2.repository;

import org.springframework.stereotype.Repository;

@Repository
public class ProductRepository {

}

OrderRepository.java

package com.newer.ioc2.repository;

import org.springframework.stereotype.Repository;

/**
 * 
 * @author 
 *
 */
@Repository
public class OrderRepository {

}

LoginRepository.java

package com.newer.ioc2.repository;

import org.springframework.stereotype.Repository;

@Repository
public class LoginRepository {

}

AccountRepository.java

package com.newer.ioc2.repository;

import org.springframework.stereotype.Repository;

/**
 * 数据操作
 * 
 * @author 
 *
 */
@Repository
public interface AccountRepository {

	/**
	 * 需要执行哪些操作
	 * 
	 * @param name
	 * @param password
	 */
	void create(String name, String password);
}

AccountRepositorySQL.java

package com.newer.ioc2.repository.mysql;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

import com.newer.ioc2.repository.AccountRepository;

@Primary
@Repository("mysql")
public class AccountRepositorySQL implements AccountRepository {

	@Override
	public void create(String name, String password) {
		System.out.println(String.format("%s, %s 存入 MySQL", name, password));

	}

}

AccountRepositoryNoSQL.java

package com.newer.ioc2.repository.mongodb;

import org.springframework.stereotype.Repository;

import com.newer.ioc2.repository.AccountRepository;


@Repository("mongodb")
public class AccountRepositoryNoSQL implements AccountRepository {

	@Override
	public void create(String name, String password) {
		System.out.println(String.format("%s, %s 存入 MongoDB", name, password));
	}

}

User.java

package com.newer.ioc2.pojo;

public class User {

}

HomeController.java

package com.newer.ioc2.controller;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.newer.ioc2.pojo.User;
import com.newer.ioc2.service.AccountService;
import com.newer.ioc2.service.OrderService;

/**
 * 控制器组件:接收请求,调用业务逻辑,分发视图或数据
 * 
 * @author 
 *
 */
@Controller
public class HomeController {

	// 通常在控制器中注入业务逻辑
	@Autowired
	AccountService accountService;

	@Autowired
	OrderService orderService;

	@ResponseBody
	@GetMapping("/")
	public String home(String name, String password) {
		accountService.create(name, password);
		return "home";
	}

	// 方法的参数
	public String other(ModelAndView mv, HttpServletRequest request, HttpServletResponse response,
			HashMap<String, Object> data, User u) {

		// 可以直接使用参数中声明的资源(容器自动给你创建并传递进来

		return "viewName";
	}

}

程序运行后:

浏览器显示的,(可以通过浏览器传入name,password)


 

 传入name,password后,控制台发生相应的变化


以上就是关于 Spring中依赖注入与容器之间的简单关系,后续功能会在下一篇博客具体说到,有问题的小伙伴欢迎留言!!!重要的是理解,理解再理解!!!

正文到此结束
本文目录