0

OK, so we are learning Spring MVC 3. And we are a little new to IoC, DI, etc. We want to clean up a lot of our old legacy mistakes. :-)

We are really liking @Autowired for our user services, etc.

However, we now have an issue that we would like to solve with Autowiring.

Let's say we have a Login bean:

public class Login {
    private String username;
    private String email;

    // getters/setters....
}

This bean should be used session wide. We want every controller to be able to access this single object.

Which I'm assuming we need in our application-config.xml

<bean id="login" class="com.example.models.Login" scope="session" />

Also, let's say we have another class as:

public class Employee {
    private String firstName;
    private String lastName;

    private Login login;

    public Employee(Login paLogin) {
        this.login = paLogin;
    }
}

And to put that in session:

<bean id="employee" class="com.example.models.Employee" scope="session" />

OK, later on in our application, we have an email notification service. That service needs to access the username and email from the Login bean AND information from the Employee bean. Granted I could access the login bean from session memory but this is just an example.

@Controller
public class EmailController {

    @Autowired
    Login login;    // this should come from session memory automatically right??

    @Autowired
    Employee employee;    // OK, this should also come from session memory.  Which contains a reference of the login too.  Correct?

    // getters/setters....


    public void sendEmails() {
        // ....
        String email = login.getEmail();
        String firstName = employee.getFirstName();
        // ....
    }
}

I hope this makes sense. What we are really wanting to accomplish is reducing XML configs, reducing constant parameter passing, minimal annotations, etc.

Any help that could point me in the right direction would be appreciated.

Thanks!

cbmeeks
  • 11,248
  • 22
  • 85
  • 136
  • I might be corrected on this but I thought you can just get Spring to instantiate your bean and NOT need to define it as session scoped (and thus just use annotations). This is because Spring, by default, creates objects as singletons, so there is only one created, which is available to any controllers that reference it. – nickdos Oct 23 '12 at 08:06
  • what problem you are facing doing this? refer to spring doc for bean scope as it will require change in web.xml too. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes – Jigar Parekh Oct 23 '12 at 09:53
  • I got down-voted because I didn't show any research effort? Funny. Had no idea the down-voter was sitting next to me as I was Googling and searching SO for the last 2 hours. Anyway...like I said we are new to Spring. I've read the docs. But we (more than one here) just aren't getting it. I've come from a .NET and Rails world so some of this is foreign to me. The problem we are getting is that 'bean b' that is supposed to be injected in 'bean a' doesn't seem to get instantiated. If we could get a nice tutorial that doesn't require reams of XML config that would also be awesome. Thanks. – cbmeeks Oct 23 '12 at 12:42
  • We can't read you thoughts, you have to include the evidence of your research in your question. With Spring 3.1 you can get away with minimal or 0 XML. Just remember any class that is referenced by `@Autowired` needs to be annotated itself with one of `@Service`, `@Component` or `@Repository` so that Spring instantiates it (you can't `new` it manually). – nickdos Oct 23 '12 at 23:26

1 Answers1

2

Couple of things about the controller you have put up.

@Controller
public class EmailController {

@Autowired
Login login;    // The container has to create a bean of type Login to autowire into EmailController

@Autowired
Employee employee;    //same as above

// getters/setters....
}

If the container has to create a singleton bean on application startup, you have to mark the Login and Employee class with annotation @Component. Even annotations like @Repository, @Service does this. You can have look at this answer for difference between these annotations.

So once you mark your classes with any of these annotations, singleton beans of respective type will be created on application startup. You will see something like this in your logs

Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6c811e18

And then a list of beans it has created. You can inject these beans to other beans. And these beans aren't stored in the session. But they are managed by the container itself.

You can do away with the xml bean definitions if your are using annotations like @Controller, @Component etc. Also you can avoid majority of your xml configuration files by using @Configuration. You can check here and here for examples.

Community
  • 1
  • 1
shazinltc
  • 3,616
  • 7
  • 34
  • 49