View
80
Download
1
Category
Preview:
DESCRIPTION
Winter is coming (Johannes vs Johanes. Nets DevDay 2012 Johannes Brodwall , Principal Architect Steria Norway @ jhannes. Why dependency detox ?. < beans default-autowire = " constructor " > - PowerPoint PPT Presentation
Citation preview
Winter is coming
(Johannes vs JohanesNets DevDay 2012
Johannes Brodwall, Principal ArchitectSteria Norway
@jhannes
<?xml version="1.0" encoding="UTF-8"?><beans default-autowire="constructor">
<bean class="no.steria.spring.ApplicationServiceImpl" />
<bean class="no.steria.spring.IncrementService" />
<bean class="no.steria.spring.ReportService" />
<bean class="no.steria.winterapp.provided.JdbcEntryDao" />
<bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/primaryDs" /> </bean></beans>
public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("..."); ApplicationService applicationService = context.getBean(ApplicationService.class); applicationService.incrementAndReport(new Date());}
Who created that object?
Is that setter still in use?
Are we sure @Transactional is
picked up?
How does @Transaction
work?!
In what <import> is that bean defined?
Where is the business logic?!
The “Service” here does nothing!
public static void main(String[] args) { ApplicationService applicationService = new ApplicationService(createDataSource()); applicationService.incrementAndReport(new Date()); }
public class ApplicationService {
private IncrementService incrementService; private ReportService reportService;
public ApplicationService(DataSource dataSource) { this(new IncrementService(dataSource), new ReportService(dataSource)); }
public ApplicationService(IncrementService incrementSvc, ReportService reportSvc) { this.incrementService = incrementService; this.reportService = reportService; }
public void incrementAndReport(Date date) { incrementService.increment(date); reportService.printReport(); }
}
public class IncrementService {
private EntryDao entryDao;
public IncrementService(DataSource dataSource) { this(new JdbcEntryDao(dataSource)); }
public IncrementService(EntryDao entryDao) { this.entryDao = entryDao; }
public void increment(Date date) { entryDao.insertEntry(new Entry(date)); }
}
Ward Cunningham:
”You know you are working on clean code when each
routine you read turns out to be pretty much what you
expected.”
Java design in 2003… really sucked
… Singleton craze
… needed dependency control
… needed more magic
public interface TransactionManager {
Transaction beginTransaction();
}
public interface Transaction extends Closeable {
void setCommit();
void close();}
@Testpublic void rollbackTransaction() throws Exception { doThrow(new RuntimeException()).when(targetObject).doIt();
try {
transactional(targetObject).doIt();
fail("Should throw exception"); } catch (RuntimeException e) { // expected }
verify(tx, never()).setCommit(); verify(tx).close();}
protected<T> T transactional(final T targetObject) { return Proxy.newProxyInstance(getClass().getClassLoader(), …, new InvocationHandler() { @Override public Object invoke(…, Method method, Object[] args) { Transaction transaction = txMgr.beginTransaction(); try {
method.invoke(targetObject, args); transaction.setCommit(); } finally { transaction.close(); } return null; } });}
Since Java 1.4!
void inTx(ExampleInterface targetObject) { try (Transaction tx = txMgr.beginTransaction()) { targetObject.doIt(); // if doIt() throws, we never get here // – then close() rolls back tx.setCommit(); }}
Java 1.7
Person-Controller
Person-Controller-
Impl
Person-Service
Person-ServiceImpl
Person-Repository
Person-Repository
Impl
PersonDao
PersonDaoImpl
Session-Factory
<?xml version="1.0" encoding="UTF-8"?><beans default-autowire="constructor">
<bean class="no.steria.spring.ApplicationServiceImpl" />
<bean class="no.steria.spring.IncrementService" />
<bean class="no.steria.spring.ReportService" />
<bean class="no.steria.winterapp.provided.JdbcEntryDao" />
<bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/primaryDs" /> </bean></beans>
public class PersonServlet extends HttpServlet {
private PersonDao personDao;
public void setPersonDao(PersonDao personDao) { this.personDao = personDao; }
@Override public void init() throws ServletException { setPersonDao(new HibernatePersonDao("jdbc/personDs")); }}
For test
New? Wut?!?!
For re
alz
public class HibernatePersonDao implements PersonDao {
public HibernatePersonDao(String jndiDataSource) { Configuration cfg = new Configuration(); cfg.setProperty(Environment.DATASOURCE, jndiDataSource); …; cfg.addAnnotatedClass(Person.class); this.sessionFactory = cfg.buildSessionFactory(); }
Hmmm…
Hmmm…
public class PersonServlet extends HttpServlet {
private PersonDao personDao;
public void setPersonDao(PersonDao personDao) { this.personDao = personDao; }
@Override public void init() throws ServletException { setPersonDao(HibernatePersonDao.getInstance()); }}
Singleton FTW!
Jason Gormanhttp://codemanship.co.uk/parlezuml/blog/?postid=1097
Announcing A Powerful New Framework:
Programming Language is a powerful new framework that enables developers to quickly and easily handle Dependency Injection, Inversion of Control, Model-View-Controller and many other
common design problems.
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); }
Hard stuff
Hard stuff
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
FooServiceImpl
ReportsController
FooController
ServiceRepository
SPRING!
Session-Factory
PersonController
ServiceRepository
InvoiceController
Repository
FooServiceImpl
ReportsController
FooController
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!
Service Locator
Session-Factory
PersonController
ServiceRepository
InvoiceController
Repository
FooServiceImpl
ReportsController
FooController
<<locator injection>>
<<locator injection>>
<<locator injection>>
<<locator in
jection>>
Takk for meg!johannes.brodwall@steria.no
http://johannesbrodwall.com
http://sterkblanding.no
http://twitter.com/jhannes
Recommended