Results 1 to 7 of 7

Thread: Problem with @Autowired and <aop:config>

  1. #1
    Join Date
    Jul 2005
    Posts
    105

    Default 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. #2
    Join Date
    Jul 2005
    Posts
    105

    Default

    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 at 08:26 AM.

  3. #3
    Join Date
    Jul 2005
    Posts
    105

    Default

    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 at 08:26 AM.

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,624

    Default

    Is there more AOP, etc. stuff in your config?
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    Jul 2005
    Posts
    105

    Default

    Quote 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>

  6. #6
    Join Date
    Jul 2005
    Posts
    105

    Default

    Quote 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 at 08:27 AM.

  7. #7
    Join Date
    Jul 2005
    Posts
    105

    Default

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •