控制反转实例

User

package user.model;

public class User {
    private String name;
    private String content;

    public User() {
        // default constructor for spring mapping
        // Spring中不可以省略空构造方法
    }

    public User(String name, String content) {
        this.name = name;
        this.content = content;
    }

    public String getName() {
        return name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

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

}

UserDao

package user.model;

import java.util.List;

public interface UserDao {

    boolean contains(String key);

    User get(String key);

    void put(User user);

    List<User> getAll();

    void delete(String key);
}

UserDaoFactory

package user.model;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component    //Component同时只能标一个,不然会报错
public class UserDaoFactory implements FactoryBean<UserDao> {
    // 返回一个UserMockDao对象
    @Override
    public UserDao getObject() {
        System.out.println("使用工厂模式创建一个UserDao的组件");
        return new UserMockDao();
    }

    // 返回一个UserMockDao类型
    @Override
    public Class<?> getObjectType() {
        return UserMockDao.class;
    }

    // 多个Controller用到UserMockDao时,只需要创建一个,共享
    @Override
    public boolean isSingleton() {
        return true;
    }
}

UserMockDao

package user.model;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/*
 * DAO - Data Access Object, 用户实现和管理数据访问的对象,比如访问数据库等
 */

//@Component  // 告诉Spring这是一个组件,可以用来注入到其他对象里
public class UserMockDao implements UserDao {

    // 这可能会用数据库访问,文件访问的逻辑替换

    private final HashMap<String, User> users = new HashMap<>();

    public UserMockDao() {
        // 模拟数据,之后会补充具体数据库的使用
        users.put("lzh", new User("lzh","master"));
        users.put("pkj", new User("pkj", "electric mouse"));

        System.out.println("创建UserMockDao!");
    }

    // 数据访问接口
    @Override
    public boolean contains(String key) {
        return users.containsKey(key);
    }

    @Override
    public User get(String key) {
        return users.get(key);
    }

    @Override
    public void put(User user) {
        users.put(user.getName(),user);
    }

    @Override
    public List<User> getAll() {
        return new ArrayList<>(users.values());
    }

    @Override
    public void delete(String key) {
        users.remove(key);
    }
}

Application

package user;

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

// 告诉Spring从这里启动
@SpringBootApplication
public class Application {

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

    // 初始化所有的组件,并且根据依赖关系,把每个组件所依赖的其他组件初始化,然后注入!

    /*
    1.创建UserController --> new UserController(UserDao); --> 需要另外一对象(组件) UserDao
    2.先创建UserMockDao --> 创建UserController
     */
}

UserController

package user;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import user.model.User;
import user.model.UserDao;

import java.util.ArrayList;
import java.util.List;

// 告诉Spring这是个Controller
// 资源的控制,资源的接口合集
// Controller本身也是一个Component
@RestController
public class UserController {

    // 依赖于UserMockDao,需要注入UserMockDao的实例
    // UserDao泛型也可以
    private UserDao userDao;

    // 使用构造方法进行注入
    public UserController(UserDao userDao) {
        this.userDao = userDao;
        System.out.println("创建UserController!");
    }

    /**
     * 响应 GET /users 这样的请求
     * 查询用户列表
     * @return 所有用户列表
     */
    @GetMapping("/users")
    List<User> listUsers() {
        return new ArrayList<>(userDao.getAll());
    }

    /**
     * 响应 GET /users/{name}
     * 通过User的name查询具体User对象
     * @param name
     * @return name确定User对象
     */
    @GetMapping("/users/{name}")
    // 从path中提取出name
    ResponseEntity<User> getUser(@PathVariable String name) {
        if (userDao.contains(name)) {
            return new ResponseEntity<>(userDao.get(name),HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }


    /**
     * 响应 POST /users 这样的请求
     * 添加一个用户到我们用户列表里
     * @param user
     * @return 返回创建成功的User对象
     */

    /*
    @PostMapping("/users")
    User newUser(@RequestBody User user) {
        users.put(user.getName(),user);
        return users.get(user.getName());
    }
    */

    /**
     * 响应 POST /users 这样的请求
     * 添加一个用户到我们用户列表里
     * @param user
     * @return 返回创建成功的User对象
     */
    @PostMapping("/users")
    ResponseEntity<User> newUser(@RequestBody User user) {
        userDao.put(user);
        // 创建成功后返回User对象,以及自定义的状态值201
        return new ResponseEntity<>(userDao.get(user.getName()), HttpStatus.CREATED);
    }


    /**
     * 响应 PUT /users/{name} 这样的请求
     * @param name
     * @param updatedUser
     * @return 修改之后的User对象
     */
    @PutMapping("/users/{name}")
    ResponseEntity<User> updateUser(@PathVariable String name,@RequestBody User updatedUser) {
        if (userDao.contains(name)) {
            User user = userDao.get(name);
            user.setContent(updatedUser.getContent());
            return new ResponseEntity<>(user,HttpStatus.OK);
        } else return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    /**
     * 响应 DELETE /users/{name} 这样的请求
     * 删除 name 确定的User对象
     * @param name
     */
    @DeleteMapping("/users/{name}")
    ResponseEntity<Void> deleteUser(@PathVariable String name) {
        if (userDao.contains(name)) {
            userDao.delete(name);
            return new ResponseEntity<>(HttpStatus.OK);
        } else return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}

总结

1.UserDao是User系列操作接口的抽象集合,用于处理User相关数据,通过UserMockDao实现具体方法内容,从而实现控制反转,在Controller中使用时
2.@Component只能标注UserMockDao或者UserDaoFactory(否则创建对象时会出现问题):

  • 标注在UserMockDao时,直接生成UserMockDao实例后注入UserController的构造方法中
  • 标注在UserDaoFactory时,采用工厂模式创建UserMockDao对象,然后注入UserController的构造方法中
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容