Spring 5.1 added following new methods in ObjectProvider interface which provides Java 8 Stream support.
default java.util.stream.Stream<T> stream()
This method returns a sequential Stream over all matching bean instances, without specific ordering guarantees (but typically in registration order).
default java.util.stream.Stream<T> orderedStream()
This method returns a sequential Stream over all matching object instances. By default elements of the stream are pre-ordered according to the bean factory's common order comparator. We can specify our own order by using @Order annotation or by implementing Ordered `interface.
Starting Spring 5.1, ObjectProvider also extends java.lang.Iterable<T> interface, that means default methods Iterable#forEach(..) and Iterable#spliterator() can also be used, along with Iterable#iterator() which is implemented by ObjectProvider .
Examples
Example bean
public class MsgBean {
private String msg;
public MsgBean(String msg) {
this.msg = msg;
}
public void showMessage() {
System.out.println("msg: " + msg);
}
.............
}
stream() example
@Configuration
public class StreamExample {
@Bean
MsgBean msgBean() {
return new MsgBean("test msg 1");
}
@Bean
MsgBean msgBean2() {
return new MsgBean("test msg 2");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(StreamExample.class);
ObjectProvider<MsgBean> beanProvider = context.getBeanProvider(MsgBean.class);
beanProvider.iterator().forEachRemaining(System.out::println);
}
} OutputMsgBean{msg='test msg 1'} MsgBean{msg='test msg 2'}
orderedStream() examples
Using @Ordered annotation
@Configuration
public class OrderedStreamExample {
@Bean
@Order(2)
MsgBean msgBean() {
return new MsgBean("test msg 1");
}
@Bean
@Order(1)
MsgBean msgBean2() {
return new MsgBean("test msg 2");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(OrderedStreamExample.class);
ObjectProvider<MsgBean> beanProvider = context.getBeanProvider(MsgBean.class);
System.out.println("-- default order --");
beanProvider.stream().forEach(System.out::println);
System.out.println("-- ordered by @Order --");
beanProvider.orderedStream().forEach(System.out::println);
}
} Output-- default order -- MsgBean{msg='test msg 1'} MsgBean{msg='test msg 2'} -- ordered by @Order -- MsgBean{msg='test msg 2'} MsgBean{msg='test msg 1'}
Using Ordered interface
public class MsgBean2 implements Ordered {
private String msg;
private int order;
public MsgBean2(String msg, int order) {
this.msg = msg;
this.order = order;
}
public void showMessage() {
System.out.println("msg: " + msg);
}
@Override
public int getOrder() {
return order;
}
.............
}
@Configuration
public class OrderedStreamExample2 {
@Bean
MsgBean2 msgBean() {
return new MsgBean2("test msg 1", 2);
}
@Bean
MsgBean2 msgBean2() {
return new MsgBean2("test msg 2", 1);
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(OrderedStreamExample2.class);
ObjectProvider<MsgBean2> beanProvider = context.getBeanProvider(MsgBean2.class);
System.out.println("-- default order --");
beanProvider.stream().forEach(System.out::println);
System.out.println("-- ordered by Ordered interface --");
beanProvider.orderedStream().forEach(System.out::println);
}
} Output-- default order -- MsgBean2{msg='test msg 1'} MsgBean2{msg='test msg 2'} -- ordered by Ordered interface -- MsgBean2{msg='test msg 2'} MsgBean2{msg='test msg 1'}
Using Iterable methods
Using Iterable#forEach() method:
@Configuration
public class IteratorExample {
@Bean
MsgBean msgBean() {
return new MsgBean("test msg 1");
}
@Bean
MsgBean msgBean2() {
return new MsgBean("test msg 2");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(IteratorExample.class);
ObjectProvider<MsgBean> beanProvider = context.getBeanProvider(MsgBean.class);
beanProvider.forEach(System.out::println);
}
} OutputMsgBean{msg='test msg 1'} MsgBean{msg='test msg 2'}
Using Iterable#iterator() method:
@Configuration
public class IteratorExample2 {
@Bean
MsgBean msgBean() {
return new MsgBean("test msg 1");
}
@Bean
MsgBean msgBean2() {
return new MsgBean("test msg 2");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(IteratorExample2.class);
ObjectProvider<MsgBean> beanProvider = context.getBeanProvider(MsgBean.class);
beanProvider.iterator().forEachRemaining(System.out::println);
}
} OutputMsgBean{msg='test msg 1'} MsgBean{msg='test msg 2'}
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 5.1.0.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|