Download - [JWAP-2] DI & Spring
Transcript
- Java
- Web
- Programming
- Advanced
- Week02
- Spring Framework
- [email protected]
- https://github.com/eternity-next/score-spring.git
- score-client-01
- class Lecture Class StandardGrader Class PassFailGrader interface Grader Dependency Use Client Dependency Use Create Dependency inject Dependency
- class Lecture Class StandardGrader Class PassFailGrader interface GraderUse Client Use Create inject class ScoreRepositoryUse
- class Lecture interface Grader class ScoreRepository Score Server 2) HTTP 1) score 3) JSON 4) score
- public class ScoreRepository { private String url; private HttpClient client; public ScoreRepository() { this.url = http://localhost:3000/scores this.client = new HttpClient( new MultiThreadedHttpConnectionManager()); } public int [] getScores() { GetMethod get = new GetMethod(url); try { if (client.executeMethod(get) == HttpStatus.SC_OK) { return new Gson().fromJson(get.getResponseBodyAsString(), int [].class); } else { return new int [0]; } } catch (Exception e) { throw new RuntimeException(e); } finally { get.releaseConnection(); } } } ScoreRepository
- public class Lecture { private ScoreRepository scoreRepository; private Grader grader; public Lecture(Grader grader) { this.grader = grader; this.scoreRepository = new ScoreRepository(); } public String grade() { return grader.grade(scoreRepository.getScores()); } } Lecture
- Problem Testability
- Transitive Dependency
- Hidden Dependency
- Transitive Dependency
- B CA Object A
- Object C
- Object B
- Object A
- Object B
- depends on
- Object C
- Object B
- depends on
- Object A
- Object C
- depends on
- class Lecture interface Grader class ScoreRepository Score Server LectureTest Transitive Dependency
- LectureTest
- Score Server
- depends on
- class Lecture interface Grader class ScoreRepository Score Server LectureTest Server Down
- LectureTest
- Score Server
- depends on
- public class Lecture { private ScoreRepository scoreRepository; private Grader grader; public Lecture(Grader grader) { this.grader = grader; this.scoreRepository = new ScoreRepository(); } public String grade() { return grader.grade(scoreRepository.getScores()); } } Lecture
- Tight Coupling
- class Lecture interface Grader class ScoreRepository Score Server LectureTest Test Fail
- LectureTest
- Score Server
- depends on
- public class Lecture { private ScoreRepository scoreRepository; private Grader grader; public Lecture(Grader grader) { this.grader = grader; this.scoreRepository = new ScoreRepository(); } public String grade() { return grader.grade(scoreRepository.getScores()); } } Hidden Dependency
- Hidden ScoreRepository
- @Test public void starndardGrade() { Lecture lecture = new Lecture(new StandardGrader()); String grade = lecture.grade(); assertEquals("A:1 B:1 C:1 D:0 F:2 ", grade); } assertEquals
- A:1 B:1 C:1 D:0 F:2 ?
- Solution Dependency Injection
- class Lecture interface Grader class ScoreRepository Score Server LectureTest Transitive Dependency
- LectureTest
- Score Server
- depends on
- class Lecture interface Grader class HttpScore Repository Score Server LectureTest Dependency Breaking
- LectureTest
- Score Server
- depends on
- interface ScoreRepository
- class Lecture interface Grader class HttpScore Repository Score Server LectureTest Dependency Breaking
- LectureTest
- Score Server
- depends on
- interface ScoreRepository
- class Lecture interface Grader class HttpScore Repository Score Server LectureTest Testable
- LectureTest
- Score Server
- depends on
- interface ScoreRepository
- public class Lecture { private ScoreRepository scoreRepository; private Grader grader; public Lecture(Grader grader) { this.grader = grader; this.scoreRepository = new ScoreRepository(); } public String grade() { return grader.grade(scoreRepository.getScores()); } } Tight Coupling &
- Hidden Dependency
- public class Lecture { private ScoreRepository scoreRepository; private Grader grader; public Lecture(Grader grader, ScoreRepository scoreRepository) { this.grader = grader; this.scoreRepository = scoreRepository; } Loose Coupling &
- Explicit Dependency
- Mock
- {50,20,70,80,90} =>A:1 B:1 C:1 D:0 F:2
- @RunWith(MockitoJUnitRunner.class) public class LectureTest { @Mock private ScoreRepository repository; @Test public void starndardGrade() { when(repository.getScores()) .thenReturn(new int [] {50,20,70,80,90}); Lecture lecture = new Lecture(new StandardGrader(), repository); String grade = lecture.grade(); assertEquals("A:1 B:1 C:1 D:0 F:2 ", grade); }
- score-client-02
- lecture = new Lecture(new StandardGrader(), new HttpScoreRepository()); lecture = new Lecture(new PassFailGrader(), new HttpScoreRepository()); Loose Coupling => Complex Object Graph
- Registry
- LectureRegistry object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture cache
- get Standard Grade Lecture get Pass Fail Grade Lecture Container
- public class Score { private static LectureRegistry lectureFactory = new LectureRegistry(); public static void main(String [] args) { Lecture lecture = null; Scanner scanner = new Scanner(System.in); try { System.out.print("grader? "); switch(scanner.next()) { case "st": lecture = lectureFactory.getStandardGradeLecture(); break; case "pf": lecture = lectureFactory.getPassFailGradeLecture(); break; default: return; } System.out.println(lecture.grade()); } finally { scanner.close(); } } } Score class
- Complex Object Graph, Simple API
- lecture = lectureFactory.getStandardGradeLecture(); lecture = lectureFactory.getPassFailGradeLecture(); Dependency Lookup
- score-client-03
- Registry?
- new?
- Dependency Injection?
- ?
- Spring Registry Spring
- Registry = Application Context Dependency Injection Framework IoC Container
- class Lecture class Standard Grader class PassFail Grader class HttpScore Repository class Lecture class Lecture class Standard Grader class HttpScore Repository class PassFail Grader Class Configuration Metadata object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture Registry
- class Lecture class Standard Grader class PassFail Grader class HttpScore Repository class Lecture class Lecture class Standard Grader class HttpScore Repository class PassFail Grader Class Configuration Metadata object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture Application Context Registry
- Refactoring
- class Lecture class Standard Grader class PassFail Grader class HttpScore Repository class Lecture Configuration Metadata object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture Application Context XML Spring GenericXml ApplicationContext
- class Lecture class Standard Grader class PassFail Grader class HttpScore Repository class Lecture Configuration Metadata XML
- Scores.xml
- Application Context Application Context
- Scores.xml
- Application Context Application Context object :HttpScore Repository httpScore Repository
- Scores.xml
- Application Context Application Context object :Standard Grader object :PassFail Grader object :HttpScore Repository httpScore Repository passFail Grader standard Grader
- Scores.xml
- Application Context Application Context object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository httpScore Repository passFail Grader standard Grader standard Grade Lecture Dependency Injection
- Sores.xml
- Application Context Application Context object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture httpScore Repository passFail Grader standard Grader standard Grade Lecture passFail Grade Lecture Dependency Injection
- Load Application Context GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:scores.xml); Application Context object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture httpScore Repository passFail Grader standard Grader standard Grade Lecture passFail Grade Lecture
- Dependency Lookup lecture = context.getBean("passFailGradeLecture", Lecture.class); Application Context object :Lecture object :Standard Grader object :PassFail Grader object :HttpScore Repository object :Lecture httpScore Repository passFail Grader passFail Grade Lecture id class
- Dependency Injection
- Dependency Lookup
- score-client-04
- Constructor Injection Discussion public Lecture(Grader grader, ScoreRepository scoreRepository) { this.grader = grader; this.scoreRepository = scoreRepository; }
- Setter Injection Discussion public void setGrader(Grader grader) { this.grader = grader; } public void setScoreRepository(ScoreRepository scoreRepository) { this.scoreRepository = scoreRepository; }
- Stateful vs Stateless Discussion
- Prototype & Singletone Stateful Stateless