有很多@Service方法来检查id是否有结果

时间:2018-10-16 02:41:18

标签: java reflection refactoring

#include <iostream>
using namespace std;

int main() {
int number;
bool flag;

    do {
        cout << "\t\t\Menu\n";
        cout << "Enter a number between 6 and 12.\n";
        cin >> number;

        if (number > 5 && number < 13) {
            flag = true;
            for(int index = 1; index <= number; ++index) {

                //Loop for spaces.
                for(int spaces = index; spaces < number; ++spaces) {
                    cout << " ";
                }

                //Loop for numbers.
                int counter = index;
                int counter2 = 1;
                for(int index2 = 1; index2 <= (2 * index - 1); ++index2) {
                    if (counter > 0) cout << counter--;
                    else cout << ++counter2;
                }

                cout << "\n";
            }

        } else cout << "Enter a valid number!\n";

    } while (!flag);

return 0;
}

这些xxxService是@Autowired属性,“ ....”表示其他类似的if语句。如何通过重构代码来避免这种情况?我试图使用反射来获取xxxService,但是我发现xxxService类可以创建,但是其中有属性,例如xxxxDao,SessionFactory(我正在使用Hibernate),这些不能通过反射创建,我该如何  这样做吗?或者是否还有其他方法可以解决if check问题?

我真正想要的是如何重构代码以使其看起来更漂亮:如何避免这么多的if语句?

3 个答案:

答案 0 :(得分:0)

考虑到所有类都共享相同的接口,可以将其所有实现注入到List <>中。假设接口名称为AppService。

@Component 
public class Example {

    private final List<AppService> appServices;

    public Example(List<AppService> appServices) {
        this.appServices = appServices;
    }

    public void verifyLogs(int id) {
        appServices.forEach(appService -> {
                if (!WebUtils.isEmpty(appService.getAppById(id))) {
                    LOGGER.info(":bind order info");
                    errorNum++;
                }
            }
        );
    }

界面类似于:

public interface AppService {
     App getAppById(int id);
}

服务:

@Service
public class AppAppService implements AppService {
    public App getAppById(int id) {
        // logic to get the app by id
   }
}

希望有帮助!

答案 1 :(得分:0)

尝试其他方法。您可以实例化这些类但不具有属性的原因是,您必须从实例实例均已初始化的Spring上下文中获取实例。

为此,您必须有权访问ApplicationContext,例如,实现ApplicationContextAware接口。

@Component
public class Example implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void verify(int id) {
      MyAppService appService = (MyAppService)  applicationContext.getAutowireCapableBeanFactory().getBean("serviceName");
    } 

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

通过这种方式,您可以使用问题中的反射方法来实现所需的目标。

答案 2 :(得分:0)

好吧,如果这是您想要的。然后,您必须使用反射。

将答案与应用程序上下文合并,就像这样:

private static final List<String> serviceClassNames = Arrays.asList(
    “appAppService”, “censusAppService”, ...)

public void verify() {
    serviceClassNames.forEach(className -> {
        Object service = applicationContext.getAutowireCapableFactory().getBean(className);

    Object app = Arrays.stream(service.getClass().getDeclaredMethods())
    .filter(method -> method.getName.equals(“getAppById”))
    .findFirst()
    .orElseThrow(() -> new RuntimeException(“Method not found!”)
    .invoke(id)

    If (!WebUtils.isEmpty(app)) {
        LOGGER.info......
    }
}

这是您需要的吗?