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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<!-- bean definitions here -->
<bean id="point" class="com.example.demo.Point">
<qualifier value="circleRelated" />
<property name="x" value="0"></property>
<property name="y" value="0"></property>
</bean>
<context:annotation-config/>
<context:component-scan base-package="com.example.demo" />
Class with main method:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@SpringBootApplication
public class SpringSecondApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecondApplication.class, args);
ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml");
Shape shape = (Shape) context.getBean("circle");
shape.draw();
}
}
Circle.java
package com.example.demo;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Component
@ComponentScan(basePackages="com.example.demo")
public class Circle implements Shape {
@Autowired
@Qualifier("circleRelated")
private Point point;
public Circle(Point point) {
super();
this.point = point;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public void draw() {
System.out.println("Draw is called");
System.out.println("center.x:" + point.getX());
System.out.println("center.y:" + point.getY());
}
}
Point.java
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Component
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;
}
}
Shape.java
package com.example.demo;
public interface Shape {
public void draw();
}
Getting error as below:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'circle': Unsatisfied dependency expressed through field 'point'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.Point' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=circleRelated)} [2m2021-03-28 12:17:31.958[0;39m [32m INFO[0;39m [35m2747[0;39m [2m---[0;39m [2m[ main][0;39m [36mConditionEvaluationReportLoggingListener[0;39m [2m:[0;39m
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. [2m2021-03-28 12:17:31.977[0;39m [31mERROR[0;39m [35m2747[0;39m [2m---[0;39m [2m[ main][0;39m [36mo.s.b.d.LoggingFailureAnalysisReporter [0;39m [2m:[0;39m
APPLICATION FAILED TO START
Description:
Field point in com.example.demo.Circle required a bean of type 'com.example.demo.Point' that could not be found.
The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) - @org.springframework.beans.factory.annotation.Qualifier(value=circleRelated)
The following candidates were found but could not be injected: - User-defined bean
Action:
Consider revisiting the entries above or defining a bean of type 'com.example.demo.Point' in your configuration.
You could import your xml-beans via @ImportResource
And just @Autowire
the applicationContext or access it via an EventListener
.
Here is an example to draw the circle when the application is ready (ApplicationReadyEvent
)
@SpringBootApplication
@ImportResource("classpath:beans.xml")
public class SpringSecondApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSecondApplication.class, args);
}
@EventListener
public void init(ApplicationReadyEvent event){
Shape shape = (Shape) event.getApplicationContext().getBean("circle");
shape.draw();
}
EDIT: reviewed my answer
@ImportResource("classpath:beans.xml")
is not strictly needed but recommend it for clarity. (beans.xml
will be auto-detected)
If you want to get a bean in the main method ( here circle
) you can, but here again, I would not recommend it.
This should work:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Shape shape = (Shape) context.getBean("circle");
shape.draw();
}
}
Things that are conflicting in your code, or could cause a conflict:
@Component
on Point
and the same bean in your beans.xml
@ComponentScan(basePackages="com.example.demo")
on Circle
: this makes no sense...ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml")
while SpringApplication.run(...)
returns an ApplicationContext