Search code examples
javaspringswingautowiredspring-annotations

Java based configuration, autowire bean with arguments


This is the first time i'm trying to write a swing app with Spring(java based configuration only, i don't want XML). The problem is that i do not know how to autowire a bean that requires an argument, in my application i will be creating large amount of JPanel(and for them LineBorder etc.) and i'm struggling to find the correct way of how to do this. Should i just create a bean definition that will return a simple JButton, set scope to "prototype", autowire it and do all the initialization after in my GUI class?

Also in swing app, should a create everything using spring?(not a single "new" keyword outside of my configuration class), like when i have

linebuttonPanel.setPreferredSize(new Dimension(0, 70));

should i instead write a method returning a new Dimension bean like this?

Dimension d = context.getBean("dimension");
d.setSize(0, 70);
linebuttonPanel.setPreferredSize(d);

Or should i move the dimension initialization into the configuration class and write this

linebuttonPanel.setPreferredSize(context.getBean("dimension", 0, 70));

I was trying to use @Autowire wherever possible and this is the problem i encountered, here is first option where i need to somehow provide the argument while autowiring

enter image description here

Second option is to implement ApplicationContextAware and use getBean method but is this the right way of how to do this for every bean?

enter image description here


Solution

  • You need an access to application context when you have to create your button.

    You can autowire ApplicationContext into your bean and lookup for Button bean from there, BUT it's extremely BAD idea. You shouldn't inject entire application context into your particular bean, it breaks loose coupling idea the spring was designed for.

    So you'd better remove ApplicationContextAware interface from your GUI class definition and delete ApplicationContext applicationContext class field as well.

    In this case it's better to make bean creation operations abstract and implement them in java based app config.

    I mean you can define abstract method

    protected abstract JButton getButton(String name)
    

    in your GUI class, so the class would become abstract as well.

    Then you can make a bean definition in your current config as follows:

    @Bean
    public GUI gui() {
        return new GUI() {
            @Override
            protected JButton getButton(String name) {
                // note, here you're referencimg your Bean jButton of scope "prototype"
                return jButton(name);
            }
        }
    }