Announcement Announcement Module
Collapse
No announcement yet.
AopProxy creation in Spring 2.5.6? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AopProxy creation in Spring 2.5.6?

    I'm trying to understand why some code is written the way it is.

    Here is some code from my AuthenticationProvider:

    Code:
    private boolean isProxy;
    private UserDao userDao;
    ...
    public Authentication authenticate(final Authentication authentication) {
      if (!this.isProxy) { this.updateUserDao() }
    
      ...normal authenticate() code...
    }
    
    private final synchronized void updateUserDao() {
        if (!AopUtils.isAopProxy(this.userDao)) {
            this.userDao = (UserDao) this.applicationContext.getBean("userDao");
            this.isProxy = AopUtils.isAopProxy(this.userDao);
        } else {
            this.isProxy = true;
        }
    }
    So, every time an authentication attempt is made, a check is made to see if the userDao is an AopProxy, and if not it loads it again from the the application context.

    When I set break points in the code, initially this.userDao is not an Aop proxy, but after the call to this.applicationContext.getBean("userDao"), it is.

    I'm using some version of Spring 2 (most likely 2.5.6). Can anyone tell me why code like this might be needed? This is the only place in the entire code base which does something like this.

    Also, isn't there a better method/place to do this? (I'm sure the authentication provider was chosen because it's guaranteed to be called soon after the app starts up.)

  • #2
    Well clearly this code is used to ensure that whenever UserDao is used in the code, it is the proxied version that is used. Probably AOP is used in the dao for crucial purposes (transactionality and / or security most likely, but without looking at the Spring config it's just an educated guess) and the coder wanted to exclude the possibility that non-proxied versions of the dao could be used throughout the code.

    The point is, if your Spring configuration is correct, you don't need a hand-made check like this. This is not just useless but potentially dangerous and certainly resource-consuming.

    Again, this is an educated guess, but probably the original coder used a flawed Spring configuration and that led to proxies not always being applied correctly. The coder then experimented unexpected behaviour, debugged the code, discovered that sometimes the dao was not proxied, and, instead of trying to correct his Spring config, implemented this quick hand-made "patch".

    Comment


    • #3
      Originally posted by Enrico Pizzi View Post

      The point is, if your Spring configuration is correct, you don't need a hand-made check like this. This is not just useless but potentially dangerous and certainly resource-consuming.
      Do you have an idea of what might be wrong with the Spring configuration?

      Some observations:

      1. The userDao bean is injected into many other beans and yet this is the only place where the Aop proxy check is made.

      2. The userDao is injected into the DaoAuthenticationProvider which itself is injected into an AuthenticationProcessingFilter.

      One theory I have is that Spring is creating the userDao bean in a phase when AOP processing is not active. Perhaps this is due to the fact that the userDao is (indirectly) needed in order to create the AuthenticationProcessingFilter. However, beans created after this phase do have AOP processing applied to them, so this hack is not needed for other beans or other places where the userDao is injected.

      Does this seem reasonable? Is there a way to defer the creation of the userDao bean until AOP processing is "active"?

      Comment


      • #4
        One theory I have is that Spring is creating the userDao bean in a phase when AOP processing is not active
        I don't think this is the case. Spring AOP is processed BEFORE beans are created, so when a certain bean is added to the context, it is always already the proxied version if the pointcut(s) match the bean.
        I still think that somewhere in your application Spring is not used correctly, but without looking at the configuration it's just an educated guess.

        Comment

        Working...
        X