AOP pointcut error - spring

I am using AOP in my application and need to define a pointcut,
I am doing that with spring configuration
<aop:aspect id="aspect" ref="loggerBean">
<aop:pointcut id="pointCut" expression="execution(public * *(..))" />
<aop:around pointcut="pointCut" method="logMethod" />
</aop:aspect>
but I am getting the exception
Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting '(' at character position 0
pointCut
^
what I am doing wrong here?

Bearing in mind the information you have provided, I've got two ideas:
Is the class that contains logMethod an #Aspect?
<aop:around pointcut-ref="pointCut" method"logMethod" /> Notice the pointcut-ref.
I believe the latter is the right one but, can't check it now.

Related

Spring AOP : Logging function not getting called via aspectJ, have attached the xml file below

Below is the XML file not sure why the function creditCardAmountBorrowedUpdation() is not getting called:
<aop:config>
<aop:aspect id="beforeTransactions" ref="authorizeCCTransactionsLogs">
<aop:pointcut
expression="execution(void AuthorizeCCTransactions.CreditCardHelper.creditCardAmountBorrowedUpdation(..))"
id="beforeDepositing"/>
<aop:before method="beforeApprovingCCTransactions" pointcut-ref="beforeDepositing"/>
<aop:after method="afterApprovingCCTransactions" pointcut-ref="beforeDepositing"/>
</aop:aspect>
</aop:config>

custom thymeleaf dialect registration causing exception

in applicationContext.xml
<bean id="templateEngine"
class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.test.custom.CustomDialact" />
</set>
</property>
</bean>
Stacktrace:
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'additionalDialects' of bean class [org.thymeleaf.spring3.SpringTemplateEngine]: Bean property 'additionalDialects' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1042)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:902)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1424)
... 50 more
i don't know but it was fixed after restarting machine. but mean while i find another solution
by extend a custom class with HashSet and in constructor add custom dialect in it and declare it in xml. provide it reference to additionalDialects . thats it .it will start running . it think it is problem related to generics as spring sometimes supply empty type
like HashSet<V> .

groovy + Spring add list in different order will throw NotWritablePropertyException

I am trying to integrate Groovy with Spring.
In one bean I would need to put in a list as property
However that only work if I define the item in list before the bean definition.
To avoid future errors...I would like to ask what is the mechanism behind compiling the context and causing the error?
The Item.groovy is a simple bean with field String itemName
My config is like
Not-working
<lang:groovy id="handler" script-source="ItemHandlerImpl.groovy">
<lang:property name="itemList">
<list>
<lang:groovy id="item1" script-source="Item.groovy">
<lang:property name="itemName" value="name1" />
</lang:groovy>
</list>
</lang:property>
</lang:groovy>
This throws
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'itemName' of bean class [org.springframework.scripting.groovy.GroovyScriptFactory]: Bean property 'itemName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1024)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:900)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1358)
... 70 more
After many attempts, this is my working config
<lang:groovy id="item1" script-source="Item.groovy">
<lang:property name="itemName" value="name1" />
</lang:groovy>
<lang:groovy id="handler" script-source="ItemHandlerImpl.groovy">
<lang:property name="itemList">
<list>
<ref bean ="item1">
</list>
</lang:property>
</lang:groovy>

Spring AOP: Adding advice in a running application

How can I add or remove Spring AOP proxies in a running application without restarting the server?
Something like this
GenericApplicationContext ctx = new GenericApplicationContext();
BeanDefinitionBuilder promotion4Advice = BeanDefinitionBuilder.rootBeanDefinition(Promotion4Action.class).addPropertyValue("discountPercentage", 0.5);
promotion4Advice.addPropertyValue("discountCode", 16);
promotion4Advice.addPropertyValue("discountComment", "50% on regular item");
ctx.registerBeanDefinition("promotion4Advice", promotion4Advice.getBeanDefinition());
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ProxyFactoryBean.class);
builder.addPropertyValue("proxyTargetClass", true);
builder.addPropertyValue("interceptorNames", new String[] {"promotion4Advice"});
ctx.registerBeanDefinition("proxyFactoryBean", builder.getBeanDefinition());
My XML config looks like this:
<bean id="promotion4Advice"
class="com.promotion.actions.Promotion4Action">
<property name="discountPercentage" value="0.5" />
<property name="discountCode" value="16" />
<property name="discountComment" value="50% on regular item" />
</bean>
<aop:config proxy-target-class="true">
<aop:aspect id="promotion4Aspect" ref="promotion4Advice">
<aop:pointcut id="promotion4PointCut"
expression="execution(* com.controller.ShoppingBagController.defaultHandler(javax.servlet.http.HttpServletRequest)) and args(request)" />
<aop:before pointcut-ref="promotion4PointCut" method="applyPromotion4"
arg-names="request" />
</aop:aspect>
<aop:aspect id="promotion4Aspect1" ref="promotion4Advice">
<aop:pointcut id="promotion4PointCut1"
expression="execution(* com.controller.ReviewOrderController.handleRequest(javax.servlet.http.HttpServletRequest)) and args(request)" />
<aop:before pointcut-ref="promotion4PointCut1" method="interceptOrderDetails"
arg-names="request" />
</aop:aspect>
<aop:aspect id="promotion4Aspect4" ref="promotion4Advice">
<aop:pointcut id="promotion4PointCut4"
expression="execution(* com.controller.ShoppingBagController.applyPromoCode(javax.servlet.http.HttpServletRequest, String, String)) and args(request, promoCode, mappedURL)" />
<aop:after pointcut-ref="promotion4PointCut4" method="interceptPromoCode"
arg-names="request,promoCode,mappedURL" />
</aop:aspect>
</aop:config>
This is one of the promotions... Like the above i have 3 other and want to be able to configure these dynamically through aop without changing the xml and restarting the server. Please help
I don't think you can, mainly because Spring wires beans during context startup. This means if bean A is injected into bean B and the former one is not wrapper with any proxy, it will be injected directly.
Now of course you can take A, wrap it in a proxy and put it back in the container (as a copy A'). But B does not know about A' at all.
If your know in advance which beans are subject to dynamic adding/removing aspects, wrap them eagerly in aspect that does nothing on startup (e.g. calling sort of NoOpStrategy). When you need to "add" the aspect, just change that strategy to something else.

Spring expression language not working with spring aop

<bean id="eddie" class="com.springinaction.Instrumentalist">
<property name="instrument" value="#{violin}"></property>
<property name="song" value="#{kenny.song}"></property>
</bean>
<bean id="violin" class="com.springinaction.Violin">
</bean>
<bean id="kenny" class="com.springinaction.Instrumentalist">
<property name="song" value="Kenny is a star,kenny is a star"></property>
<property name="instrument" ref="saxopone"></property>
</bean>
<aop:config>
<aop:aspect ref="audience">
<aop:before pointcut="execution(* com.springinaction.Performer.perform(..))" method="takeSeats()"/>
<aop:after-throwing method="demandRefund" pointcut="execution(* com.springinaction.Performer.perform(..))"/>
</aop:aspect>
</aop:config>
In the above code,I am injecting song , instrument property of eddie bean using spring expression language. But, song property not injected properly..and i am getting the below error:
Exception in thread "main"
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'eddie'
defined in class path resource
[spring-config.xml]: Initialization of
bean failed; nested exception is
org.springframework.beans.factory.BeanExpressionException:
Expression parsing failed; nested
exception is
org.springframework.expression.spel.SpelEvaluationException:
EL1008E:(pos 6): Field or property
'song' cannot be found on object of
type '$Proxy4' at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
at
org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at
org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at
com.springinaction.Main.main(Main.java:10)
Instrument property is injected properly where as song property is not injected and this is happening because of aop only..
when i comment out <aop:config> it is working fine..
Anything wrong?
Did you try
<aop:config proxy-target-class="true">
...
</aop:config>
This way you get a dynamic subclass and the property should be available in the proxy created via Spring AOP.
The default behaviour of Spring AOP is to create a Java proxy for the interfaces, so the properties of any classes won't be accessible through the proxy.

Resources