deepakraut
deepakraut

Reputation: 953

Exception while using ProxyFactoryBean

I am trying to implement ProxyFactoryBean for creating AOP proxies but getting some errors. Can anyone tell me where I'm going wrong.

Code and exception track trace is given below:

Perfomer.java

    public interface Performer {
        public void perform();
    }

Juggler.java

    public class Juggler implements Performer {
        private int beanBags;
        public Juggler(){
            beanBags =3;
        }
        public Juggler (int beanBags){
            this.beanBags=beanBags;
        }
        @Override
        public void perform() {
            System.out.println("Juggling "+beanBags+" BeanBags...");            
        }
    }

Audience.java

    @Aspect
    public class Audience{
        @Pointcut("execution(* com.org.Performer.perform(..))")
        public void performance(){}

        @Before("performance()")
        public void takeSeats(){
            System.out.println("The audience is taking their seats.");
        }
        @Before("performance()")
        public void turnOffCellPhones(){
            System.out.println("The audience is turning off their cellphones.");
        }
        @AfterReturning("performance()")
        public void applaud(){
            System.out.println("CLAP CLAP CLAP CLAP CLAP");
        }
        @AfterThrowing("performance()")
        public void demandRefund(){
            System.out.println("Boo! We want our money back!");
        }
        @After("performance()")
        public void goHome(){
            System.out.println("The audience is going home!");
        }
        @Around("performance()")
        public void watchTime(ProceedingJoinPoint joinPoint){
            try{
                long startTime=System.currentTimeMillis();
                joinPoint.proceed();
                long endTime=System.currentTimeMillis();
                System.out.println("Time taken: "+(endTime-startTime));
            }
            catch (Throwable t){t.printStackTrace();}
        }
    }

TestClass.java

    public class TestClass {
        public static void main(String args[]) {
            ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-config.xml");

            Performer performer=(Performer)applicationContext.getBean("proxyDuke");
            performer.perform();   
        }
    }

spring-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="Duke" class="com.org.Juggler" ><constructor-arg value="15" /></bean>
    <bean id="audience" class="com.org.Audience"/>

    <bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>

        <bean id="proxyDuke" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="Duke"/>
            <property name="interceptorNames">
                <list>
                    <value>audience</value>
                    <value>debugInterceptor</value>
                </list>
            </property>
        </bean>
         <aop:scoped-proxy proxy-target-class="false" />
    </beans>

But is giving following exception

Exceptions:

Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [scoped-proxy]
Offending resource: class path resource [spring-config.xml]
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.fatal(FailFastProblemReporter.java:59)
    at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:68)
    at org.springframework.beans.factory.parsing.ReaderContext.fatal(ReaderContext.java:55)
    at org.springframework.beans.factory.xml.NamespaceHandlerSupport.findParserForElement(NamespaceHandlerSupport.java:84)
    at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:73)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1419)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1409)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:140)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:111)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
    at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
    at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:522)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.org.TestClass.main(TestClass.java:15)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Upvotes: 3

Views: 4327

Answers (1)

James K
James K

Reputation: 326

As an initial stab check that you have the spring-aop jar on your classpath when you run the test. If you look at the init method in org.springframework.aop.config.AopNamespaceHandler which is the default handler for the aop namespace, it registers the handler for 'scoped-proxy'.

HTH!

James

Addendum: After looking in more detail the problem is that you can't specify:

 <aop:scoped-proxy proxy-target-class="false" /> 

as a standalone element. It needs to be inside the bean definition i.e.:

<bean id="Duke" class="com.org.Juggler">
    <constructor-arg value="15" />
    <aop:scoped-proxy proxy-target-class="false" />
</bean>

If you don't want any of the beans to be cglib proxies then use:

<aop:config proxy-target-class="false" />

There are other problems too as in when specifying interceptor names to ProxyFactoryBean they must be of type Advice,Advisor,Interceptor etc. which Audience is not. If you can omit the debug interceptor bean then you need only define the following:

<bean id="Duke" class="com.org.Juggler">
    <constructor-arg value="15" />
</bean>
<bean id="audience" class="com.org.Audience" />
<aop:aspectj-autoproxy proxy-target-class="false" />    

The last line <aop:aspectj-autoproxy..... /> will check for annotations in classes defined and auto-proxy Juggler.

Lastly you then need to change the code so you are retrieving "Duke" as opposed to the proxy, ie.

Performer performer = (Performer)applicationContext.getBean("Duke");
performer.perform();

Upvotes: 4

Related Questions