Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a Spring session scoped bean based on user properties

I've developed a Spring Web-MVC application. I have some offices in my project. Each user belongs to an office. user.getOfficeType() returns an integer representing the user's office type. If the office type is 1, the user belongs to Office1 and etc. However I want to inject the authenticated user's office into my service classes:

class MyService{
   @Autowired
   Office currentOffice;
   ...
}

I read the Spring docs. I need a session scoped bean to inject it into my service classes.

applicationContext.xml:

<mvc:annotation-driven />
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<context:annotation-config />
<context:component-scan base-package="com.package.controller" />
<context:component-scan base-package="com.package.service" />
...
<bean id="office" class="com.package.beans.Office" scope="session">
    <aop:scoped-proxy/>
</bean>

enter image description here

I have three implementations of the Office interface. Once a user requests a resource, I want to be aware of his Office. So I need to inject his session-scoped Office into my service classes. But I don't know how to instantiate it according to the user's office. please help!

like image 980
Dariush Jafari Avatar asked Oct 16 '15 12:10

Dariush Jafari


People also ask

Why Spring bean scope is singleton by default?

When a bean is a singleton, only one shared instance of the bean will be managed and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned. Only when you have to keep some session details you should use for example session scope.

How can we change the scope of a bean in Spring?

If the scope is set to prototype, the Spring IoC container creates a new bean instance of the object every time a request for that specific bean is made. As a rule, use the prototype scope for all state-full beans and the singleton scope for stateless beans.

Which attribute is used to set the scope of the bean?

Which attribute is used to set the scope of the bean? Explanation: Scope attribute defines the scope of a bean.


1 Answers

I found a solution! I declared an OfficeContext that wraps the Office and also implements it.

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class OfficeContext implements InitializingBean, Office {

   private Office office;

   @Autowired
   private UserDao userDao;

   @Autowired
   private NoneOffice noneOffice;
   @Autowired
   private AllOffice allOffice;
   @Autowired
   private TariffOffice tariffOffice;
   @Autowired
   private ArzeshOffice arzeshOffice;

    public Office getOffice() {
       return this.office;
    }

   @Override
   public void afterPropertiesSet() throws Exception {
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
       if (auth.isAuthenticated()) {
           String name = auth.getName(); //get logged in username
           JUser user = userDao.findByUsername(name);
           if (user != null) {
               this.office = noneOffice;
           } else {
               OfficeType type = user.getOfficeType();
               switch (type) {
                   case ALL:
                       this.office = allOffice;
                       break;
                   case TARIFF:
                       this.office = tariffOffice;
                       break;
                   case ARZESH:
                       this.office = arzeshOffice;
                       break;
                   default:
                       this.office = noneOffice;
               }
           }
       } else {
           this.office = noneOffice;
       }

   }

   @Override
   public OfficeType getType() {
       return office.getType();
   }

   @Override
   public String getDisplayName() {
       return office.getDisplayName();
   }

}

and in my service classes I injected the OfficeContext.

@Service
public class UserService {

   @Autowired
   UserDao userDao;

   @Autowired
   OfficeContext office;

   public void persist(JUser user) {
       userDao.persist(user);
   }

   public void save(JUser user) {
       userDao.save(user);
   }


}
like image 108
Dariush Jafari Avatar answered Sep 25 '22 15:09

Dariush Jafari