At first, I have a spring application works fine:
but when to add aop config to aop.xml like this, It throws a very lang exception.
this is AOP.java:
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.animal.Cat;
public class AOP {
public static void main(String args[]){
System.out.println("1");
BeanFactory factory = new ClassPathXmlApplicationContext("aop.xml");
Cat c1 =(Cat)factory.getBean("cat1");
System.out.println("2");
c1.mark();
}
}
this is Cat.java:
package com.animal;
public class Cat {
public void mark(){
System.out.println("cat is mark");
}
}
this is Rat.java:
package com.animal;
public class Rat {
public void sleep(){
System.out.println("rat is sleep");
}
public void run(){
System.out.println("rat running");
}
}
this is xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<bean id="cat1" class="com.animal.Cat">
</bean>
<bean id="rat1" class="com.animal.Rat">
</bean>
<aop:config>
<aop:pointcut id="cat_mark" expression="execution(public void com.animal.Cat.mark())" />
<aop:aspect ref="rat1">
<aop:before method="sleep" pointcut-ref="cat_mark" />
<aop:after method="run" pointcut-ref="cat_mark" />
</aop:aspect>
</aop:config>
As you can see, this is a very simple application, I just want to use spring AOP to make rat do some action before cat going to mark.
I have config XML file which copies from some tutorial, but I can not find what is wrong with it.
yeah, I miss aspectjweaver.jar which org.springframework.context required.
This is the solution:
You have edited your question, so I am editing my answer because now I can reproduce your problem.
Actually your original pointcut was correct. Forget what I said about it being wrong, I parsed it wrong when I first saw it. Just change it back to using only a single *, please:
execution(* com.animal.Cat.mark(..))
Now I think your problem is far simpler, judging from the callstack you posted earlier but cut off in order to replace it by a screenshot of an incomplete callstack. But I found it in your question's history, looking at the old version:
...
Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
I believe you just forgot to put aspectjweaver.jar (or a versioned name like aspectjweaver-1.8.13) on the classpath when running the application. Do that and it should go away. If I do that, your application prints:
1
Apr 20, 2018 6:04:34 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFORMATION: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#18769467: startup date [Fri Apr 20 18:04:34 ICT 2018]; root of context hierarchy
Apr 20, 2018 6:04:35 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFORMATION: Loading XML bean definitions from class path resource [aop.xml]
2
rat is sleep
cat is mark
rat running
Related
I'm trying to create a simple spring app, but when i use #Component annotation for a bean instead of defining it in spring.xml file, I'm getting this error.
Aug 09, 2017 11:06:03 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#7e32c033: startup date [Wed Aug 09 11:06:03 IST 2017]; root of context hierarchy
Aug 09, 2017 11:06:03 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'oval' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1078)
at org.sumit.javabrains.DrawingApp.main(DrawingApp.java:24)
My Classes are al follows:
1. DrawingApp.java (main class)
public package org.sumit.javabrains;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DrawingApp {
public static void main(String[] args) throws InterruptedException {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Oval oval = (Oval) context.getBean("oval");
oval.draw();
}
}
2. Spring.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.sumit.javabrains" />
<context:annotation-config />
<bean id="focus" class="org.sumit.javabrains.Point" scope="singleton">
<property name="x" value="-7" />
<property name="y" value="8" />
</bean>
</beans>
3 Point.java
package org.sumit.javabrains;
public class Point {
private int x;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
4 Oval.java
package org.sumit.javabrains;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
#Component
public class Oval {
private Point focus;
public Point getFocus() {
return focus;
}
#Resource
public void setFocus(Point focus) {
this.focus = focus;
}
public void draw() {
System.out.println("Point focus is: ("+focus.getX()+", "+focus.getY()+")");
}
}
could someone be able to help what caused this issue. I'm using spring 4.3.10 RELEASE
That's because your component scan is scanning the wrong packages
<context:component-scan base-package="com.sumit.javabrains" /> - Wrong
It should be scanning as follows:
<context:component-scan base-package="org.sumit.javabrains" /> - Correct
you must define all your bean in spring.xml. in this scenario you missed the Oval class in you spring configuration files. define the Oval class as a bean in your spring.xml file.
or
edit your component-scan tag and put the correct package.
Two thing went wrong here.
1. You've mentioned wrong base package in your xml file
com.sumit.javabrains must be replaced with org.sumit.javabrains
Replace #Resource with #Resource #Qualifier("focus").By default beans marked with ‘#Component’ will have the same name as the class
Try using #ComponentScan instead of #Component on top of the Oval class.
I wasn't using a spring.xml file (just the default spring boot configuration instead), my #SpringBootApplication annotated class was one package level deeper than my #Component class, which made that the #Component class wasn't picked up.
E.g.:
com.company.base/ComponentAnnotatedClass.java
com.company.base.application/MySpringBootApplication.java
I am a new bee to spring and am writing my first spring program.I have the following files.
package com.springstarter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringUser
{
public static void main( String[] args )
{
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
SpringStarter starter = ( SpringStarter ) context.getBean( "springstarter" );
starter.getMessage();
}
}
I have a bean called SpringStarter
package com.springstarter;
public class SpringStarter
{
private String message;
public String getMessage()
{
return message;
}
public void setMessage( String message )
{
this.message = message;
}
}
Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="springstarter" class="com.springstarter.SpringStarter">
<property name="message" value="Hello World!"/>
</bean>
</beans>
The following is the package structure:
I have run the program in eclipse Mars, using Spring 4.2.4.
I didn't find any compilation issues, but the program is just showing the following logs.
Jan 14, 2016 10:36:08 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#73a83205: startup date [Thu Jan 14 10:36:08 IST 2016]; root of context hierarchy
Jan 14, 2016 10:36:08 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [Beans.xml]
The expected output though, is Hello World!
Kindly let me know if i'm making any obvious mistakes.
Nothing wrong, but to print the output on console, so you should use it like:
System.out.println(starter.getMessage());
I am experimenting on "beforeAdvice" over "JointPoints" in spring aop. it's pretty simple i am calling target method. before executing target class method, before() method should execute.
ClientApp:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import com.nt.services.LoanApprover;
public class ClientApp {
public static void main(String[] args) {
//activate ioc container
ApplicationContext context = new FileSystemXmlApplicationContext("src/com/nt/cfgs/applicationContext.xml");
//get bean
LoanApprover approver = context.getBean("pfb",LoanApprover.class);
//call b.method
approver.approver();
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="auditAdvice" class="com.nt.aspect.MyBeforeAdvice" />
<bean id="target" class="com.nt.services.LoanApprover" />
<bean id="pfb" class="
org.springframework.aop.framework.ProxyFactoryBean ">
<property name="target" ref="target" />
<property name="interceptorNames">
<list>
<value>
auditAdvice
</value>
</list>
</property>
</bean>
</beans>
MyBeforeAdvice.java
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice{
#Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("I am in MyBeforeAdvice class");
}
}
LoanApprover.java
public class LoanApprover {
public void approver(){
System.out.println("I am in LoanApprover method");
}
}
when i run this application i am getting this exception.
Aug 13, 2015 12:16:04 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext#7c6cd67b: startup date [Thu Aug 13 12:16:04 IST 2015]; root of context hierarchy
Aug 13, 2015 12:16:04 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [G:\java\Frameworks\SpringAOP\AOPProj3(Before Advice)\src\com\nt\cfgs\applicationContext.xml]
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pfb': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '
auditAdvice
' is defined
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObject FromFactoryBean(FactoryBeanRegistrySupport.java:175)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFr omFactoryBean(FactoryBeanRegistrySupport.java:103)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanIn stance(AbstractBeanFactory.java:1517)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(Abstract BeanFactory.java:251)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBe anFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractA pplicationContext.java:962)
at test.ClientApp.main(ClientApp.java:13)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '
auditAdvice
' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefi nition(DefaultListableBeanFactory.java:694)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBean Definition(AbstractBeanFactory.java:1168)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(Abstract BeanFactory.java:281)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBe anFactory.java:194)
at org.springframework.aop.framework.ProxyFactoryBean.initializeAdvisorChain(ProxyF actoryBean.java:460)
at org.springframework.aop.framework.ProxyFactoryBean.getObject(ProxyFactoryBean.ja va:244)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObject FromFactoryBean(FactoryBeanRegistrySupport.java:168)
... 6 more
please anyone tell me why i am getting this exception?
Simply change
<value>
auditAdvice
</value>
to
<value>auditAdvice</value>
It seems like spring is using whitespaces and newline symbols as ID here.
Further information on that topic is available here.
Hope that helps.
I'm setting up a project using Spring 3.2.9.FINAL and I'm just unable to load some properties I've stored in an external file. That's how my application-context.xml looks:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:property-placeholder
location="file:/home/myapp/settings.properties" />
<bean class="foo.Test">
<property name="property" value="${test.property}" />
</bean>
</beans>
That's the content of my settings.properties file:
test.property=Hello world
The foo.Test class is very simple and only contains a String property. In my main method I do this:
public class App {
public static void main(String[] args) {
DefaultListableBeanFactory dlbf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(dlbf);
reader.loadBeanDefinitions(new ClassPathResource(
"/application-context.xml", Test.class));
System.out.println(dlbf.getBean(Test.class).getProperty());
}
}
That's what I get when executing it:
Jun 12, 2014 12:03:38 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [application-context.xml]
${test.property}
I tried several workarounds based in answers from SO, but nothing seems to work. What am I doing wrong?
You are loading beans into a BeanFactory whereas you should use an ApplicationContext.
public class App {
public static void main(String[] args) {
ApplicationContext ctx d= new ClassPathXmlApplicationContext("application-context.xml");
System.out.println(ctx.getBean(Test.class).getProperty());
}
}
See the reference guide for an explanation of the differences.
Application context loads all beans from spring XML file and doesn't support selective lazy loading but using XML bean factory version (check precise class name ) one can selectively load beans. Please test.
I have destroy method in my bean but it is not showing in the out put. Could you please help me here.
package com.vaannila;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloWorldApp {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Ticket helloWorld = (Ticket) context.getBean("ticket");
helloWorld.setTicketNo("ABC009");
helloWorld.display();
context.close();
}
}
below is my xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloWorld" class="com.vaannila.HelloWorld">
<property name="message" value="Hello World!"></property>
</bean>
<bean id="ticket" class="com.vaannila.Ticket"
scope="prototype" init-method="init" destroy-method="destroy"/>
</beans>
and Ticket class is below
package com.vaannila;
public class Ticket {
private String ticketNo="";
public String getTicketNo() {
return ticketNo;
}
public void setTicketNo(String ticketNo) {
this.ticketNo = ticketNo;
}
public void display()
{
System.out.println("Your Ticket No. is"+ ticketNo);
}
public void init()
{
System.out.println("Bean is ready You can use it now");
}
public void destroy()
{
System.out.println("Bean is going to destroy");
}
}
The out put is giving for init method but not for destroy method..
If i changed the init-method and destroy-method as default as below it is giving error in destroying the bean called "helloWorld"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="init" default-destroy-method="destroy">
<bean id="helloWorld" class="com.vaannila.HelloWorld">
<property name="message" value="Hello World!"></property>
</bean>
<bean id="ticket" class="com.vaannila.Ticket"
scope="prototype"/>
</beans>
When a bean is defined as prototype, the bean container creates new instances of this been whenever it is asked for that bean. That's the idea behind prototype-scoped beans.
After they are created, the container gives up responsibility for the bean. It cannot know if you are still holding a reference to it, or when is the moment you drop the last reference. This is true even after the container is closed. (The container is not the garbage collector.) So it cannot possibly know when is the right moment to call the destroy method.
If you need deinitialization for your ticket, you will have to call such a method from your code directly I think (assuming that it makes no sense to have singleton tickets).