Announcement Announcement Module
Collapse
No announcement yet.
Problem with @Autowired and <aop:config> Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with @Autowired and <aop:config>

    I'm trying to autowire a DAO that requires a String property. Here is the relevant part of the DAO implementation:

    Code:
    @Repository("accountDao")
    public class AccountDaoJdbcImpl implements AccountDao {
    	private String schemaName;
    	
    	@Autowired
    	public void setSchemaName(@Qualifier("schemaName") String schemaName) {
    		this.schemaName = schemaName;
    	}
    ...
    }
    In my XML file, I define 'schemaName' with a property placeholder like so:

    Code:
    	<bean id="schemaName" class="java.lang.String">
    		<constructor-arg value="${schemaName}" />
    	</bean>
    Now this by itself works great. No problems whatsoever. However, when I add an advisor to the ApplicationContext like so:

    Code:
    	<aop:config>
    		<aop:pointcut id="dao"
    			expression="@target(org.springframework.stereotype.Repository)" />
    		<aop:advisor pointcut-ref="dao"
    			advice-ref="daoAdvice" />
    	</aop:config>
    ...this appears to cause the 'schemaName' bean to no longer be of type java.lang.String. Instead it is now a proxy (as discovered while debugging). This causes an IllegalArgumentException when the setSchemaName(String schemaName) method is invoked on the DAO.

    First off, am I doing something wrong? If I am not, should I submit a JIRA for this?

    For the record, I am doing the following component scan, and the bean is definitely getting included in the candidates. (I have various other DAO impls in the same package base, hence am excluding those).

    Code:
    	<context:component-scan
    		base-package="com.my.company.daoimpl"
    		use-default-filters="false">
    		<context:include-filter type="annotation"
    			expression="org.springframework.stereotype.Repository" />
    		<context:exclude-filter type="regex" expression=".*DaoMockImpl" />
    		<context:exclude-filter type="regex"
    			expression=".*DaoHibernateImpl" />
    	</context:component-scan>
    Thanks in advance,

    Jonathan

  • #2
    Having given this a bit more thought over lunch, my suspicion is that the problem stems from the fact that the autowiring is to a class (java.lang.String) which is ultimately being used as the class itself and not an implemented interface.

    I obviously don't need the 'schemaName' bean to be a candidate for autoproxying. Is there a way to tell the ApplicationContext not to proxy this particular bean?
    Last edited by fiddlerpianist; Feb 8th, 2008, 08:26 AM.

    Comment


    • #3
      Update: It appears that the AspectJAwareAdvisorAutoProxyCreator is the culprit here. It thinks that a class of java.lang.String can pass the pointcut of: @target(org.springframework.stereotype.Repository) . Anyone know enough AspectJ syntax to help me make that the class filter's match() method return false?
      Last edited by fiddlerpianist; Feb 8th, 2008, 08:26 AM.

      Comment


      • #4
        Is there more AOP, etc. stuff in your config?

        Comment


        • #5
          Originally posted by mdeinum View Post
          Is there more AOP, etc. stuff in your config?
          Nothing in an <aop:config> block. I am using a TransactionProxyFactoryBean on an 'accountService' bean which is dependent on the 'accountDao' bean, but I'm fairly certain that's not relevant here. I'll post what I have anyways. In case you cannot tell, I'm in the process of converting over to the aop:config syntax. I'm trying the DAO layer before I do the service layer.

          Code:
          	<bean id="accountService" parent="baseServiceProxy">
          		<property name="target">
          			<bean class="com.mycompany.serviceimpl.AccountServiceImpl">
          				<property name="accountDao" ref="accountDao"/>
          			</bean>
          		</property>
          	</bean>
          
          
          	<bean id="baseServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
          		<property name= "transactionManager" ref= "transactionManager" />
          		<property name="preInterceptors">
          			<list>
          				<ref bean="serviceJamonInterceptor"/>
          			</list>
          		</property>
          		<property name="transactionAttributes">
          			<props>
          				<prop key="*">PROPAGATION_REQUIRED, -Exception</prop>
          			</props>
          		</property>	
          	</bean>
          
          
          	<bean id="serviceJamonInterceptor" class="com.mycompany.tools.timing.JamonPerformanceMonitorInterceptor">
          		<property name="summaryMonitorName">
          			<value>APP.summary.32-spring-services</value>
          		</property>
          		<property name="prefix">
          			<value>APP.spring.service.</value>
          		</property>
          	</bean>

          Comment


          • #6
            Originally posted by fiddlerpianist View Post
            Update: It appears that the AspectJAwareAdvisorAutoProxyCreator is the culprit here. It thinks that a class of java.lang.String can pass the pointcut of: @target(org.springframework.stereotype.Repository) . Anyone know enough AspectJ syntax to help me make that the class filter's match() method return false?
            Making the pointcut be:
            Code:
            !within(java.lang.String) && @target(org.springframework.stereotype.Repository)
            fixed it. So all of the beans of certain classes you don't want eligible for autoproxying you would have to add a !within section for the pointcut.

            The question is now if this is a bug. Instead of an IllegalArgumentException, I would think that somewhere I should get a warning or an error that says that I cannot proxy a class (or that CGLIB is unavailable)? Though I guess that the post-processor would have to know how the object could be cast.
            Last edited by fiddlerpianist; Feb 8th, 2008, 08:27 AM.

            Comment


            • #7
              This is probably all because I don't know how to write pointcuts. This is really want I wanted to do from the start:

              Code:
              <aop:pointcut id="dao" expression="@within(org.springframework.stereotype.Repository)" />
              Much nicer.

              Comment

              Working...
              X