0
votes

I have two maven module:

  1. logic (Spring project with beans etc.) - packed to .jar

  2. Web (Vaadin project with spring nature) - packet to .war

In Web .pom I have dependecy to logic. In java code autowired etc. is ok. I want use beans from logic in Web project.

My web.xml (Web project): path: ../src/main/webapp/WEB-INF

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext.xml

    </param-value>
</context-param>

My application context: (path: ../src/main/webapp/WEB-INF)

<beans ...
<context:annotation-config />

<import resource="logic.xml"/>

<context:component-scan base-package="b2b"
    annotation-config="true" />

logic.xml contains configuration for beans in logic module. Base package name is b2b.

In UI class I have:

@Autowired
private CompanyService companyService;

I try in many ways to get beans, but always companyService is null after start Web.

What I should add to get beans from logic module visible in Web module?

UI class:

@Theme("mytheme")
@SuppressWarnings("serial")
@Controller
public class MyVaadinUI extends UI
{ }

I also make as mentions here for vaadin V7: enter link description here

but not help.

This is my UI class:

enter code here
@Theme("mytheme")
@SuppressWarnings("serial")
@Controller
public class MyVaadinUI extends UI
{

 SpringContextHelper helper = new SpringContextHelper(VaadinServlet.getCurrent().getServletContext());

private static Logger LOGGER = Logger.getLogger(MyVaadinUI.class);

@WebServlet(value = "/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = MyVaadinUI.class, widgetset = "b2b.frontend.AppWidgetSet")
public static class Servlet extends VaadinServlet {
}

@Override
protected void init(VaadinRequest request) {
    final VerticalLayout layout = new VerticalLayout();
    layout.setMargin(true);
    setContent(layout);
    final CompanyService companyService = (CompanyService) helper.getBean("companyService");

    Button button = new Button("Click Me");
    button.addClickListener(new Button.ClickListener() {
        public void buttonClick(ClickEvent event) {
            //layout.addComponent(new Label("Thank you for clicking"));

            LOGGER.info("pushed the button");
            layout.addComponent(new Label("aa " +companyService +" Thank you for clicking"));

        }
    });
    layout.addComponent(button);
}

}

2

2 Answers

0
votes

You didn't presented your UI class. I suspect that UI is not a Spring managed bean, thus autowiring is off. Or your UI is annotated as Spring bean, but is created with new operator, not taken from Spring context.

Well, if you made it as you explained, it must work. No mercy. I made a simple project https://github.com/michaldo/multi-module-vaadin-spring and it works

0
votes

You can split your UI in 2 layers - views (UI) and controllers (intermediate class between view and your logic classes). Your controller can be created from view in standard way i.e. with new operator.

Then annotate your controller class with @Configurable:

@Configurable
public class MyController 
{
   @Autowired
   private MyService service;
}

Configurable tells Spring that this bean created out of Spring context should still be a subject for dependency injection. To make this work, you'll need AspectJ runtime on your classpath + add aspectj compiling stage to your build - change pom.xml for ui project as follows:

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- Aspectj plugin to make Spring aware of non-managed
        beans and support autowiring -->
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>aspectj-maven-plugin</artifactId>
      <version>1.4</version>
      <configuration>
        <!-- Required as the plugin does not resolve this by default -->
        <source>1.6</source>
        <target>1.6</target>
        <aspectLibraries>
          <aspectLibrary>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
          </aspectLibrary>
        </aspectLibraries>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>test-compile</goal>
          </goals>
        </execution>
      </executions>
    </plugin> 

I'm using this approach in my project and works pretty well.