Annotation application of spring IOC
To use annotation injection, you need to define a scan package
In previous projects, we all assigned beans or some attributes through xml files. In fact, there is another way of annotation. Many of them are used in enterprise development. Adding annotations to beans can quickly register beans to ioc container.
1. Register the bean into the IOC container using annotations
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- If you want to customize bean Object added to IOC In the container, you need to add some annotations on the class Spring There are 4 main components to add notes: @Controller:Controller, recommended for controller Add this annotation to the layer @Service:Business logic. It is recommended to add this annotation to the business logic layer @Repository:For warehouse management, it is recommended to add this annotation to the data access layer @Component:Add this annotation to components that do not belong to the above base layer Note: Although we artificially add different annotations to different layers, in spring It seems that you can add any annotation at any layer spring The bottom layer will not give specific level verification annotations. The purpose of this writing is only to improve readability. It is the laziest way Is to give it to everyone who wants it IOC Container managed bean Object addition component annotation Using annotations requires the following steps: 1,Add any of the above four annotations 2,Add a component that automatically scans annotations. This operation requires dependencies context Namespace 3,Add automatically scanned labels context:component-scan Note: when registering components with annotations, it is the same as registering components with configuration files, but note: 1,Component id By default, the first character of the class name of the component is lowercase. If you need to change the name, you can add it directly in the annotation 2,Components are singleton by default,If you need to configure the multi instance mode, you can add it under the annotation@Scope annotation --> <!-- Define the base package for automatic scanning: base-package:Specify the base package to scan, spring At startup, all annotated classes under the basic package and sub package will be automatically Scan in IOC container --> <context:component-scan base-package="com.mashibing"></context:component-scan> </beans>
PersonController.java
package com.mashibing.controller; import org.springframework.stereotype.Controller; @Controller public class PersonController { public PersonController() { System.out.println("create object"); } }
PersonService.java
package com.mashibing.service; import org.springframework.stereotype.Service; @Service public class PersonService { }
PersonDao.java
package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository("personDao") @Scope(value="prototype") public class PersonDao { }
2. Define classes to include and classes not to include when scanning packages
After the basic scanning package is defined, it may be necessary to selectively configure whether to register bean s into the IOC container in some cases. At this time, it can be configured in the following ways.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.mashibing" use-default-filters="false"> <!-- After defining the package for basic scanning, you can exclude some classes in the package and use the following methods: type:Represents the rule for the specified filter annotation: Exclude according to the annotation. Components marked with the specified annotation are not allowed,expression Indicates the annotation to filter assignable: Specifies that a specific class is excluded according to the class, expression Represents a specific class name that is not registered aspectj: Later aop Explain what to use when aspectj Expression, No custom: Define a typeFilter,Write your own code to determine which classes are filtered out, No regex: Use regular expression filtering without --> <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--> <!--Specify which components are scanned only. By default, all components are scanned. Therefore, to configure at this time, you need to component-scan Add to label use-default-filters="false"--> <context:include-filter type="assignable" expression="com.mashibing.service.PersonService"/> </context:component-scan> </beans>
3. Auto injection using @ AutoWired
The @ AutoWired annotation is required to realize automatic injection by using annotation.
PersonController.java
package com.mashibing.controller; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired private PersonService personService; public PersonController() { System.out.println("create object"); } public void getPerson(){ personService.getPerson(); } }
PersonService.java
package com.mashibing.service; import com.mashibing.dao.PersonDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonService { @Autowired private PersonDao personDao; public void getPerson(){ personDao.getPerson(); } }
PersonDao.java
package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository public class PersonDao { public void getPerson(){ System.out.println("PersonDao:getPerson"); } }
Note: when AutoWired annotation is used, automatic assembly is implemented according to type.
1. If only one is found, assign the value directly,
2. If it is not found, an exception will be thrown directly,
3. If more than one is found, it will continue to match according to the variable name as the id,
1. Assembly directly on matching
2. If there is no match, an exception will be reported directly
PersonServiceExt.java
package com.mashibing.service; import com.mashibing.dao.PersonDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonServiceExt extends PersonService{ @Autowired private PersonDao personDao; public void getPerson(){ System.out.println("PersonServiceExt......"); personDao.getPerson(); } }
PersonController.java
package com.mashibing.controller; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired private PersonService personServiceExt; public PersonController() { System.out.println("create object"); } public void getPerson(){ personServiceExt.getPerson(); } }
You can also use the @ Qualifier annotation to specify the name of the id so that spring does not use the variable name. There are two cases when using the @ Qualifier annotation:
1. If found, assemble directly
2. If it cannot be found, an error will be reported
PersonController.java
package com.mashibing.controller; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired @Qualifier("personService") private PersonService personServiceExt2; public PersonController() { System.out.println("create object"); } public void getPerson(){ personServiceExt2.getPerson(); } }
Through the above code, we can find that @ AutoWired can certainly be assembled. If it is not assembled, an error will be reported.
4. @ AutoWired can be defined on the method
When we look at the source code of @ AutoWired annotation, we find that this annotation can be used not only on member variables, but also on methods.
PersonController.java
package com.mashibing.controller; import com.mashibing.dao.PersonDao; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Qualifier("personService") @Autowired private PersonService personServiceExt2; public PersonController() { System.out.println("create object"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); // personServiceExt2.getPerson(); } /** * When there is @ AutoWired annotation on the method: * 1,This method will be called automatically when the bean is created * 2,Each parameter of this method is automatically injected with a value * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("This method is called:"+personDao); } /** * @Qualifier Annotations can also act on attributes to be used as IDs to match objects in the container, if not * If this annotation is used, match directly by type * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("This method is called:"+personService); } }
5. Annotation for auto assembly @ AutoWired, @ Resource
When using automatic assembly, besides @ AutoWired annotation, you can also use @ Resource annotation. You need to know the difference between the two annotations.
1. @ AutoWired: is the annotation provided in spring, @ Resource: is the annotation defined in the jdk, which relies on the java standard
2. By default, @ AutoWired is assembled by type. By default, dependent objects must exist. By default, @ Resource is matched by name, and the name attribute can be specified.
3. @ AutoWired is only suitable for spring framework, and @ Resource has better scalability
PersonController.java
package com.mashibing.controller; import com.mashibing.dao.PersonDao; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class PersonController { @Qualifier("personService") @Resource private PersonService personServiceExt2; public PersonController() { System.out.println("create object"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); personServiceExt2.getPerson(); } /** * When there is @ AutoWired annotation on the method: * 1,This method will be called automatically when the bean is created * 2,Each parameter of this method is automatically injected with a value * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("This method is called:"+personDao); } /** * @Qualifier Annotations can also act on attributes to be used as IDs to match objects in the container, if not * If this annotation is used, match directly by type * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("This method is called:"+personService); } }
6. Generic dependency injection
In order to explain generic dependency injection, we need to write a basic case first according to our previous knowledge:
Student.java
package com.mashibing.bean; public class Student { }
Teacher.java
package com.mashibing.bean; public class Teacher { }
BaseDao.java
package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository public abstract class BaseDao<T> { public abstract void save(); }
StudentDao.java
package com.mashibing.dao; import com.mashibing.bean.Student; import org.springframework.stereotype.Repository; @Repository public class StudentDao extends BaseDao<Student>{ public void save() { System.out.println("Save students"); } }
TeacherDao.java
package com.mashibing.dao; import com.mashibing.bean.Teacher; import org.springframework.stereotype.Repository; @Repository public class TeacherDao extends BaseDao<Teacher> { public void save() { System.out.println("Save teacher"); } }
StudentService.java
package com.mashibing.service; import com.mashibing.dao.StudentDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class StudentService { @Autowired private StudentDao studentDao; public void save(){ studentDao.save(); } }
TeacherService.java
package com.mashibing.service; import com.mashibing.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService { @Autowired private TeacherDao teacherDao; public void save(){ teacherDao.save(); } }
MyTest.java
import com.mashibing.service.StudentService; import com.mashibing.service.TeacherService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.sql.DataSource; import java.sql.SQLException; public class MyTest { public static void main(String[] args) throws SQLException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); StudentService studentService = context.getBean("studentService",StudentService.class); studentService.save(); TeacherService teacherService = context.getBean("teacherService",TeacherService.class); teacherService.save(); } }
The above code is a function that we can complete before, but we can think about whether the code of the Service layer can be rewritten:
BaseService.java
package com.mashibing.service; import com.mashibing.dao.BaseDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; public class BaseService<T> { @Autowired BaseDao<T> baseDao; public void save(){ System.out.println("Automatically injected objects:"+baseDao); baseDao.save(); } }
StudentService.java
package com.mashibing.service; import com.mashibing.bean.Student; import com.mashibing.dao.StudentDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class StudentService extends BaseService<Student> { }
TeacherService.java
package com.mashibing.service; import com.mashibing.bean.Teacher; import com.mashibing.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService extends BaseService<Teacher>{ }