Djorgje Popovic just published an article on the Step builder pattern which includes a nice video explaining the how and the why of this design.
So thanks to Djorgje and enjoy the video.
New ideas pass through three periods:
1) It can’t be done.
2) It probably can be done, but it’s not worth doing.
3) I knew it was a good idea all along!
- Arthur C. Clarke
package com.marco.springchain; public class User { private final String name; private final char gender; public User(String name, char gender) { super(); this.name = name; this.gender = gender; } public String getName() { return name; } public char getGender() { return gender; } }
package com.marco.springchain; public interface Printer { void print(User user); }
package com.marco.springchain; import org.springframework.core.Ordered; public abstract class GenericPrinter implements Printer, Ordered { public void print(User user) { String prefix = "Mr"; if (user.getGender() == 'F') { prefix = "Mrs"; } System.out.println(getGreeting() + " " + prefix + " " + user.getName()); } protected abstract String getGreeting(); public int getOrder() { return Ordered.LOWEST_PRECEDENCE; } }
package com.marco.springchain; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; @Component public class HelloPrinter extends GenericPrinter { private static final String GREETING = "Hello"; @Override protected String getGreeting() { return GREETING; } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } }
package com.marco.springchain; import org.springframework.stereotype.Component; @Component public class WelcomePrinter extends GenericPrinter { private static final String GREETING = "Welcome to the autowired chain"; @Override protected String getGreeting() { return GREETING; } @Override public int getOrder() { return 1; } }
package com.marco.springchain; import org.springframework.stereotype.Component; @Component public class GoodbyePrinter extends GenericPrinter { private static final String GREETING = "Goodbye"; @Override protected String getGreeting() { return GREETING; } @Override public int getOrder() { return 2; } }
package com.marco.springchain; import org.springframework.stereotype.Component; @Component public class CleaningMemoryPrinter extends GenericPrinter { private static final String GREETING = "Cleaning memory after"; @Override protected String getGreeting() { return GREETING; } }
package com.marco.springchain; import org.springframework.stereotype.Component; @Component public class CleaningSpacePrinter extends GenericPrinter { private static final String GREETING = "Cleaning space after"; @Override protected String getGreeting() { return GREETING; } }
package com.marco.springchain; import java.util.Collections; import java.util.List; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.stereotype.Component; @Component public class PrinterChain { @Autowired private List<Printer> printers; @PostConstruct public void init() { Collections.sort(printers, AnnotationAwareOrderComparator.INSTANCE); } public void introduceUser(User user) { for (Printer printer : printers) { printer.print(user); } } }
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd" default-lazy-init="true"> <context:component-scan base-package="com.marco.springchain"/> </beans>
package com.marco.springchain; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); PrinterChain printerChain = (PrinterChain) context.getBean("printerChain"); printerChain.introduceUser(new User("Marco Castigliego", 'M')); printerChain.introduceUser(new User("Julie Marot", 'F')); } }
Hello Mr Marco Castigliego Welcome to the autowired chain Mr Marco Castigliego Goodbye Mr Marco Castigliego Cleaning space after Mr Marco Castigliego Cleaning memory after Mr Marco Castigliego Hello Mrs Julie Marot Welcome to the autowired chain Mrs Julie Marot Goodbye Mrs Julie Marot Cleaning space after Mrs Julie Marot Cleaning memory after Mrs Julie Marot
<queue name="phaseQueueFromEngine"> <entry name="/queue/phaseQueueFromEngine"/> </queue>
<acceptor name="in-vm"> <factory-class>org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory</factory-class> </acceptor> <connector name="in-vm"> <factory-class>org.hornetq.core.remoting.impl.invm.InVMConnectorFactory</factory-class> </connector>
<acceptor name="netty"> <factory-class>org.hornetq.integration.transports.netty.NettyAcceptorFactory</factory-class> <param key="host" value="${host:localhost}"/> <param key="port" value="${port:5445}"/> </acceptor>
<connector name="remote-engine-connector"> <factory-class> org.hornetq.integration.transports.netty.NettyConnectorFactory</factory-class> <param key="host" value="172.x.x.62"/> <param key="port" value="5445"/> </connector>
package com.marco.test;
package com.marco.test;