- Objective - to register a
Classroombean which mediates a compositeStudentsandInstructorsbean reference. - Purpose - to demonstrate the use of
- Bean registration
- Dependency Injection
- IOC Container
AnnotationConfigApplicationContext- Annotations
@Bean@DependsOn@Autowired@PostConstruct@Config@SpringBootTest@Qualifier
- Do NOT clone this repository until completing
Part 0.0 - You may structure this project and the packaging how you please, however keep in mind that
@Configurationscans from current directory down. - Until
Part 10, this project is nearly identical to theLearnerLabcompleted in the past.
- Navigate to start.spring.io
- In the
Search for Dependenciesinput box search forDevToolsWeb
- Select
Generate Project - After the project has completed downloading, navigate to the download directory and unzip the project folder.
- At the root directory of the project, clone this repository.
- Move all files from the
demoproject generated bystart.spring.io, into the newly clonedlearnerlabfolder. - Open the project via its
pom.xmlfrom IntelliJ > File > Open- Be sure to
Open as Projectwhen prompted
- Be sure to
- Create a
Personclass.- The class should declare a
finalfield namedidof typelong. - The class should declare a field named
nameof typeString. Personconstructor should have a parameter of typeLong id, String namewhich sets each of the fields to their respective value.- The class should define a
getId()method which returns thePersonobject'sidfield. - The class should define a
getName()method which returns thePersonobject'snamefield. - The class should define a
setName()method which sets thePersonobject'snamefield.
- The class should declare a
- Create a
Learnerinterface.Learnershould declare one method signature:- Method name:
learn - Method parameters:
double numberOfHours - Method return-type:
void
- Method name:
- Create a
Studentclass such that:Studentis a subclass ofPersonStudentimplements theLearnerinterfaceStudentshould have an instance variabletotalStudyTimeof typedoubleStudentshould have a concrete implementation of thelearnmethod which increments thetotalStudyTimevariable by the specifiednumberOfHoursargument.Studentshould have agetTotalStudyTime()method which returns thetotalStudyTimeinstance variable.
- Create a
Teacherinterface.-
Teachershould declare ateachmethod signature:- Method name:
teach - Method parameters:
Learner learnerdouble numberOfHours
- Method return-type:
void
- Method name:
-
Teachershould declare alecturemethod signature:- Method name:
lecture - Method parameters:
Iterable<? extends Learner> learnersdouble numberOfHours
- Method return-type:
void
- Method name:
-
- Create an
Instructorclass such that:Instructoris a subclass ofPersonInstructorimplements theTeacherinterfaceInstructorshould have a concrete implementation of theteachmethod which invokes thelearnmethod on the specifiedLearnerobject.Instructorshould have a concrete implementation of thelecturemethod which invokes thelearnmethod on each of the elements in the specified array ofLearnerobjects.numberOfHoursshould be evenly split amongst the learners.double numberOfHoursPerLearner = numberOfHours / learners.length;
- Create an abstract
Peopleclass- The class signature should be parameterized with
PersonTypesuch thatPersonTypeis a sub class ofPerson. - The class should implement
Iterableof typePersonType. - Upon construction
Peopleshould consume aListofPersonTypeand set it to a respectivepersonListfield. - The class should define a constructor which consumes a variable number of
PersonTypeobjects and sets thepersonListfield respectively. - The class should define a method named
addwhich adds aPersonTypeto thepersonList. - The class should define a method named
removewhich removes aPersonTypefrom thepersonList. - The class should define a method named
sizewhich returns the size ofpersonList. - The class should define a method named
clearwhich clears ourpersonListfield. - The class should define a method named
addAllwhich adds anIterableofPersonTypeobjects to the compositepersonList.- This method will NOT take an argument of
Collection<PersonType>
- This method will NOT take an argument of
- The class should define a method named
findByIdwhich makes use of along idparameter to return aPersonTypeobject with the respectiveidfield. - The class should define a method named
findAllwhich returns the compositepersonList.
- The class signature should be parameterized with
- Create a
Studentsclass.- The class should be a subclass of
Peopleof parameterized typeStudent. - The class should consume a variable number of
Studentobjects upon construction and pass them to the super constructor.
- The class should be a subclass of
- Create a
Instructorsclass.- The class should be a subclass of
Peopleof parameterized typeInstructor. - The class should consume a variable number of
Instructorobjects upon construction and pass them to the super constructor.
- The class should be a subclass of
- Create a
Classroomclass.- The class should consume and set composite reference to an
InstructorsandStudentsobject upon construction - The class should define a method
hostLecturewhich makes use of aTeacher teacher, double numberOfHoursparameter to host alectureto the compositepersonListfield in thestudentsreference.
- The class should consume and set composite reference to an
- Each of the following
Configclasses should have a class-signature annotation of@Configuration- this annotation tells spring to scan for
@Beandefinitions within the scope of the class, and register them to the IOC Container forInjectandAutowireuse later.
- this annotation tells spring to scan for
- Classroom should define getters for each of its fields.
-
@Autowired- injects bean by type
- can be used alone.
- If is used alone, it will be wired by type
- If more than one bean of same type are declared in the container
@Autowireddoes not know which beans to use for injection.
-
@Qualifier- injects bean by specified name
- supports fields, setter, constructors and multi-argument methods injection
- together with
@Autowired, clarifies which beans to be wired by specifying the bean name (wired by name)
- Note: The creation of this class will demonstrate an implementation of bean registration in Spring.
- The class should define a method named
currentStudents()which returns aStudentsrepresentative of the current cohort of students.- the method should be annotated with
@Bean(name = "students")- this ensures the Spring container registers the bean with the respective name.
- a
@Beanwhosenameattribute is not specified defaults to the name of the method it is annotating.
- the method should be annotated with
- The class should define a bean named
previousStudents()which returns aStudentsrepresentative of the previous cohort of students.
- The class should define a bean named
tcUsaInstructors()which returns anInstructorsrepresentative of the Tech Connect USA instructors. - The class should define a bean named
tcUkInstructors()which returns anInstructorsrepresentative of the Tech Connect UK instructors. - The class should define a bean named
instructorswhich returns allInstructorsemployed at ZipCodeWilmington- annotate this bean with
@Primary- this ensures Spring will inject this bean in the case that an
Autowireannotation is not supplied with aQualifierannotation
- this ensures Spring will inject this bean in the case that an
- annotate this bean with
- The class should define a bean named
currentCohort()which returns aClassroomobject whose dependencies areinstructorsandstudents - The class should define a bean named
previousCohort()which returns anClassroomobject whose dependencies areinstructorsandpreviousStudents - Note: it is sometimes useful (although not always necessary) to use the
@DependsOnannotation to help the Spring framework and other readers of the code to understand what order beans should be executed.@DependsOn({"instructors", "students"})
- Each of the following
Testclasses should be annotated with@RunWith(SpringRunner.class)- enforces which strategy
junitshould use to run tests
- enforces which strategy
@SpringBootTest- indicates that this class is a Spring Boot test class
- provides support to scan for a
ContextConfigurationthat tells the test class how to load theApplicationContext. - If no
ContextConfigurationclasses are specified as a parameter to the@SpringBootTestannotation, the default behavior is to load theApplicationContextby scanning for a@SpringBootConfigurationannotation on a class in the package root.
- Each bean can be injected into the class scope using
@Autowiredalong with@Qualifier(name = "beanname")
- Create a
TestStudentConfigclass in thetestpackage. - The class should ensure that each
Beanin theStudentConfigclass is configured as expected. - Tip: You can use the
toStringmethod to get a representation of the aggregate state of anyPeopleobject.
- Create a
TestInstructorConfigclass in thetestpackage. - The class should ensure that each
Beanin theTestInstructorConfigclass is configured as expected.
- Create a
TestClassroomConfigclass in thetestpackage. - The class should ensure that each
Beanin theTestClassroomConfigclass is configured as expected.
- Annotating a class signature with
@Componentallows Spring to register the class as aBeanimplicitly.
- Create an
Alumnicomponent which autowiresStudentsof the previous cohort andInstructors - Create an
executeBootcampmethod which teaches eachStudentin the compositeStudentsatotalNumberOfHoursof1200.- Annotate this method with
@PostConstruct- denotes that this method must be executed before the class is put into an IoC container
- Annotate this method with
- Create a getter for each of the fields.
-
Write a test class which ensures that each
Studentin theAlumniclass has been taught1200hours upon injection of theAlumnidependency. -
Ensure the
numberOfHoursTaughthas been evenly distributed amongst each of the instructors. -
Tip: How to derive
numberOfHoursTaughtdynamically
int numberOfInstructors = instructors.size();
int numberOfStudents = students.size();
double numberOfHoursToTeachEachStudent = 1200;
double numberOfHoursToTeach = numberOfHoursToTeachEachStudent * numberOfStudents;
double numberOfHoursPerInstructor = numberOfHoursToTeach / numberOfInstructors;