Dependency injection when you only have one dependency JavaZone Johannes Brodwall, Recovering Spring...

Post on 01-Apr-2015

216 views 0 download

Tags:

Transcript of Dependency injection when you only have one dependency JavaZone Johannes Brodwall, Recovering Spring...

Dependency injection when you only have one dependency

JavaZone

Johannes Brodwall, Recovering Spring User

Steria Norway

Let’s get rid ofdogmatic dependency

injection

Does this look familiar?

Person-Controller

Person-Controller-

Impl

Person-Service

Person-ServiceImpl

Person-Repository

Person-Repository

Impl

PersonDao

PersonDaoImpl

Session-Factory

Customer

Invoice

Order

Product

No more:

this.personService =new PersonServiceImpl(sessionFactory)

Instead:

<bean id="personDao" class=“…springmadness.dao.impl.PersonDaoImpl"> <property name="sessionFactory" …/></bean>

(Or)

@Autowired private PersonService personService;

Why?

Why?

(dear God, why?!)

Testing

Multiple implementations

Multiple implementations

(Really?)

Configuration

Configuration

(Often one)

Ordnung muss sein!

(Ordnung muss sein!)

Hobgoblin of little minds

- Ralph Waldo Emerson

Alternative

Session-Factory

PersonController

ServiceRepository

public class PersonController { private PersonService personService;

@Autowired public PersonController(SessionFactory sf) { this.personService = new PersonServiceImpl(sf); }

public class PersonController { private PersonService personService;

@Autowired public PersonController(SessionFactory sf) { this.personService = new PersonServiceImpl(sf); }

public class PersonServiceImpl implements … { private PersonRepository personRepo;

public PersonServiceImpl(SessionFactory sf) { this.personRepo = new PersonRepositoryImpl(sf); }

public class PersonController { private PersonService personService;

@Autowired public PersonController(SessionFactory sf) { this.personService = new PersonServiceImpl(sf); } public PersonControllerImpl(PersonService ps) { this.personService = ps; }

public class PersonController { private PersonService personService;

@Autowired public PersonController(SessionFactory sf) { this.personService = new PersonServiceImpl(sf); } public PersonControllerImpl(PersonService ps) { this.personService = ps; }

For Spring

For mocking

SPRING!

Session-Factory

PersonController

ServiceRepository

InvoiceController

Repository

FooServiceImpl

ReportsController

FooController

Look ma!No Spring!

Session-Factory

PersonServlet

Locator(singleton O_O)

”Injected” by servlet

public class PersonController extends HttpServlet { private PersonService personService; public PersonController() { } public PersonController(PersonService personService) { this.personService = personService; } @Override public void init() throws ServletException { SessionFactory sf = HibernateLookup.getInstance(getServletContext()); this.personService = new PersonServiceImpl(sf); }

public class PersonController extends HttpServlet { private PersonService personService; public PersonController() { } public PersonController(PersonService personService) { this.personService = personService; } @Override public void init() throws ServletException { SessionFactory sf = HibernateLookup.getInstance(getServletContext()); this.personService = new PersonServiceImpl(sf); }

For mocking

Look, ma! No Spring!

Session-Factory

PersonController

ServiceRepository

InvoiceController

Repository

FooServiceImpl

ReportsController

FooController

<<locator injection>>

<<locator injection>>

<<locator injection>>

<<locator in

jection>>

Bonus: Generic Repository

public interface Repository {

<T> T retrieve(Class<T> type,Serializable id);

Serializable save(Object object);

<T> List<T> find(Specification<T> spec);

Transaction beginTransaction();}

@RunWith(RepositoryTestRunner.class)public class PersonControllerTest { private Repository repository; private PersonController personController; public PersonControllerTest(Repository repo) { this.repository = repo; this.personController = new PersonController(repo); }

@Testpublic void should_show_person() { Person person = new Person(); Long id = (Long) repository.save(person); ModelAndView show = personController.show(id); assertEquals(person, show.getModel().get("person"));}

public class RepoTestRunner extends Suite { public RepoTestRunner(Class<?> testClass) { super(testClass, createRunners(testClass)); } static List<Runner> createRunners(Class<?> testClass) { List<Runner> runners = new ArrayList<Runner>();

runners.add(testRunner(testClass, new HashMapRepository())); if (!isRunningInInfinitest()) {

runners.add(testRunner(testClass, hibernateRepository())); } return runners; }

What Spring taught me

Be aware of dependencies!

Avoid differences between test and prod

Stay the heck away from frameworks!

Collapse service chains

Takk for meg!johannes.brodwall@steria.no

http://johannesbrodwall.com

http://sterkblanding.no

http://twitter.com/jhannes