【问题标题】:Spring IoC - constructing context dependent beans?Spring IoC - 构建上下文相关的bean?
【发布时间】:2012-05-03 19:53:24
【问题描述】:

考虑以下代码:

@Service
class UserSpecificService {
    @Autowired ServiceA serviceA;
    @Autowired ServiceB serviceB;
    @Autowired User user;

    public void doUserSpecificThings() {
        // consume serviceA, serviceB and user here
    }
}

@Service class ServiceA {}
@Service class ServiceB {}

@Service
class Facade {
    public void doThingsForUser(Long userId) {
        User user = userService.getById(userId);
        UserSpecificService userSpecificService = ...; // !!!
        userSpecificService.doUserSpecificThings();
    } 
}

问题是关于标有// !!! 的行。有什么方法可以构造UserSpecificService 而不实现我自己的工厂,它知道ServiceAServiceB,并且只需要User 的实例来实例化UserSpecificService

如果这很重要 - 我将在 Spring MVC 中使用 Facade,尽管我不希望它依赖于此。

谢谢!

【问题讨论】:

标签: java spring dependency-injection ioc-container


【解决方案1】:

这里有一个建议:

  • 让所有符合userSpecificService 条件的服务(我猜是ServiceA 和serviceB)都有一个通用接口
  • 让该接口有两个方法 - doUserSpecificThing()isEligibleFor(user)
  • 使用@Autowired List<YourInterface> list
  • 在您的doThingsForUser() 方法中迭代给定接口的所有实例的列表,并为每个实例检查它是否适合给定用户。如果是 - 调用该方法。

【讨论】:

    【解决方案2】:

    如果您询问是否可以动态创建 UserSpecificService 而无需手动设置服务,请尝试以下操作:

    @Configurable
    class UserSpecificService {
        @Autowired private ServiceA serviceA;
        @Autowired private ServiceB serviceB;
        private User user;
    
        public UserSpecificService(User user){
            this.user = user;
        }
    
        public void doUserSpecificThings() {
            // consume serviceA, serviceB and user here
        }
    }
    
    @Service class ServiceA {}
    @Service class ServiceB {}
    
    @Service
    class Facade {
        public void doThingsForUser(Long userId) {
            User user = userService.getById(userId);
            UserSpecificService userSpecificService = new UserSpecificService(user);
            userSpecificService.doUserSpecificThings();
        } 
    }
    

    请注意,您需要配置 spring 上下文以扫描 @Configurable。为此,您只需将<context:spring-configured/> 添加到您的应用程序上下文文件中。另一种方法是:

    @Service
    class UserSpecificService {
        @Autowired private ServiceA serviceA;
        @Autowired private ServiceB serviceB;
    
        public void doUserSpecificThings(User user) {
            // consume serviceA, serviceB and user here
        }
    }
    
    @Service class ServiceA {}
    @Service class ServiceB {}
    
    @Service
    class Facade {
        public void doThingsForUser(Long userId) {
            User user = userService.getById(userId);
            userSpecificService.doUserSpecificThings(user);
        } 
    }
    

    根据您的具体应用,这种方法可能会更好。

    【讨论】:

      猜你喜欢
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      • 2016-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多