控制反转实例

作者: 迷路的丸子 | 来源:发表于2019-01-06 13:31 被阅读1次

    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时,直接生成UserMockDao实例后注入UserController的构造方法中
    • 标注在UserDaoFactory时,采用工厂模式创建UserMockDao对象,然后注入UserController的构造方法中

    相关文章

      网友评论

        本文标题:控制反转实例

        本文链接:https://www.haomeiwen.com/subject/itrsrqtx.html