Date post: | 01-Apr-2015 |
Category: |
Documents |
Upload: | trevion-alleyne |
View: | 219 times |
Download: | 0 times |
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 [email protected]
http://johannesbrodwall.com
http://sterkblanding.no
http://twitter.com/jhannes