BeanRepository的依赖注入

哦,不,又发生了! 有,另一个依赖注入框架...

为什么?

过去,我想启动一个可以在java沙箱中运行的项目,并且想使用依赖注入。 首先,我以为我可以只使用Spring的依赖机制(春天的背景),但事实并非如此:Spring广泛使用反射,沙箱中不允许使用反射。

下一次尝试的结果几乎相同:Guice。 现在,当我根据需要尝试此操作时,某些系统属性出现错误,不允许从沙箱中读取这些属性。 今天,我不记得确切的属性和错误。

在这一点上,我不想尝试其他框架,但是我知道有很多框架。 当然,有些框架没有使用反射。 我认为创建自己的DI框架并查看要解决的问题以符合我的期望可能很酷。 还有一点:编码很有趣。

最初的期望

  • 某种依赖注入单例豆和原型豆没有思考和注释用Java代码配置

这些期望会在一段时间后扩大。 以及我完成的项目Bean存储库开始了。

发生了什么?

However, the first result was a Service Locator. A bean has to ask activly for an other beans. Over the time the API evolved and now, I think I can say it is a mix of a Service Locator and Dependency Injection framework. It depends what you want to do, and how you do it. In this link Martin Fowler describes his idea about both approaches.

我可以看到一些代码吗?

这是一个非常简单的示例,包含三个类。 他们使用该程序的案例只是为了打印出命令行参数。

这是我们的用例,只是一种服务:

public class ArgumentPrinter {

    private final ArgsProvider argsProvider;

    /**
     * The ArgsProvider is responsible for getting the command line arguments,
     *  so we need it as a dependency. The ArgsProvider bean is provided by
     *  the BeanRepository.
     */
    public ArgumentPrinter(final ArgsProvider argsProvider) {
        this.argsProvider = argsProvider;
    }

    public void printCommandLineArgs() {

        // Isn't it a nice use case? :-)
        System.out.println("Commandline args[]:");

        for (String arg : argsProvider.get()) {
            System.out.println(" * '" + arg + "'");
        }
    }
}

的Bean存储库是一种容器,因此我们需要一个入口点来执行我们自己的代码:

/**
 * Every bean, that implements ApplicationStartedListener, will be triggered
 *  right after the BeanRepository is built. This should be used to execute code
 *  on startup.
 */
public class StartupListener extends ApplicationStartedListener {

    private final ArgumentPrinter argumentPrinter;

    public StartupListener(final ArgumentPrinter argumentPrinter) {
        this.argumentPrinter = argumentPrinter;
    }

    @Override
    public void onEvent(final ApplicationStartedEvent event) {

        // the entry point

        System.out.println("Application started");

        argumentPrinter.printCommandLineArgs();
    }
}

在这一点上,我们只想念入门类,而Bean存储库。

public class SimpleExampleApp implements BeanRepositoryConfigurator {

    public static void main(String[] args) {

        // Set args manually without configuring IDE run configs
        // -> not needed for real applications
        args = new String[] {"argument 1", "argument 2", "value"};

        // Start the application with dependency injection support
        //  1.: parameter: commandline args[]
        //  2.: parameter: Some class that implements BeanRepositoryConfigurator
        BeanRepositoryApplication.run(args, new SimpleExampleApp());
    }

    @Override
    public void configure(final BeanRepository.BeanRepositoryBuilder builder) {

        // This method is used to configure the available beans an how
        //  they depends on each other.
        // The scheme of the singleton method is:
        //  1.: type of the bean
        //  2.: reference to the constructor of the bean
        //  3., 4., 5., 6., 7.: the types of the needed beans

        builder
                           // type of the bean    // constructor ref    // type of reference
                .singleton(StartupListener.class, StartupListener::new, ArgumentPrinter.class)
                           // type of the bean    // constructor ref    // type of reference
                .singleton(ArgumentPrinter.class, ArgumentPrinter::new, ArgsProvider.class);
                // the ArgsProvider is a bean which is provided by the BeanRepository, to get
                //  the command line args
    }
}

可以引用的bean有一个限制。 当前,bean只能具有5个或更少的依赖项。 由于不使用反射,因此可以通过手动编码来实现填充。 在这种情况下:用一种具有不同参数数量的方法创建接口。 对于我来说,这足够了。

An other point is, that cyclic references are not supported directly. It is possible, but with some extra coding. See this example.

其他的东西

还有其他功能,本文未列出。

  • 其他范围提供者工厂别名...

我在哪里可以买到?

试试看:

<dependency>
  <groupId>com.github.tinosteinort</groupId>
  <artifactId>beanrepository</artifactId>
  <version>1.7.0</version>
</dependency>

获得见解:

github-logo-6a5bca60a4ebf959a6df7f08217acd07ac2bc285164fae041eacb8a148b1bab9.svgtinosteinort / beanrepository

A Dependency Injection / Service Locator Library

BeanRepository - Dependency Injection / Service Locator

This framework is the implementation of a mix of the Service Locator Pattern and a the Dependency Injection Pattern. These patterns are described by Martin Fowler in this article. The BeanRepository does not use reflection for injecting beans. Because of that fact, it can be used in the Java sandbox, where reflection is not allowed.

Features

  • simple, self-explanatory and failsafe configuration in Java code
  • no use of reflection or annotations
  • constructor injection
  • support for singletons, prototypes and instances
  • provider
  • factories
  • aliases for beans
  • fail fast on start up
  • execute code after initialisation of the bean (post construct)
  • configurable if singletons are lazy initialised or not
  • detect beans of a specific type
  • modularity possible

Limitations

  • cyclic references not supported directly. But if needed, see CyclicReferenceExampleApp for a solution
  • no request or session scope
  • no initialisation code allowed in constructor
    • constructor may be called…

from: https://dev.to//tinosteinort/dependency-injection-with-the-beanrepository-f58

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值