Table of contents
③Add annotations to store Bean objects (5 types of annotations and method annotations can be used)
Class annotations (written on the class, acting on the class)
@Controller: class marked as a controller
Why are so many annotations needed?
Method annotations (annotations acting on methods) @Bean
Why not just add @Bean annotations, but also need to add class annotations?
Summarize the usage rules of @Bean annotation:
④ Get the Bean object from Spring (object assembly/object injection)
Three ways of object injection:
1. Property injection (@Autowired)
2. Construction method injection (officially recommended writing method)
@Resource annotation and its difference from @Autowired
2. Supported injection methods are different
3. The supported parameters are different
① Obtain the dependencies of spring-context and spring-beans from the Maven central warehouse, and introduce the dependencies into pom.xml
Configure as follows:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.24</version>
</dependency>
</dependencies>
② Configure the scanning path
Find the relevant configuration code previously saved in Gitee:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) -->
<content:component-scan base-package="com.demo.spring.beans"></content:component-scan>
</beans>
Configure the spring-config.xml file in the resources file and copy the above content (note: the configuration scanning root path needs to be changed to be consistent with your own)
③Add annotations to store Bean objects (5 types of annotations and method annotations can be used)
1: Use five types of annotations:
@Controller[控制器]
,@Service[服务]
,@Repository[仓库]
,@Configuration[配置]
,Component[组件]
2: By method annotation:
@Bean方法
Class annotations (written on the class, acting on the class)
@Controller: class marked as a controller
Controller: the class corresponding to the Controller in the three-tier architecture .
The parameter passed in the @Controller annotation is the name of this class object .
package com.demo.spring.beans;
import org.springframework.stereotype.Controller;
@Controller("Student")
public class Student {
public void sayHi(){
System.out.println("Hi Student");
}
}
It should be noted that if we pass in parameters in the @Controller annotation, then we must follow the name of the parameter when using it:
If it is different, the Bean object will not be obtained:
And, if no parameter is passed to @Controller, it is named with a small hump by default (except for the case where the first two letters of the class name are capitalized, such as SUser, then the name is also the default)
The above reasons are still due to Spring's source code:
Find these two methods in the source code:
@Service
The role is the same as that of the Controller, and is used to mark the objects of the "business logic layer".
@Repository
The role is the same as that of the Controller, used to mark the object of the "persistence layer"
@Component
If it does not belong to any of the previous 3 layers, then this annotation can be considered as a "tool".
@Configuration
The role is the same as that of the Controller, used to mark the "configuration class".
The above annotations have the same effect, so I won’t demonstrate them one by one here.
Why are so many annotations needed?
This is to make the code more readable, allowing programmers to intuitively judge the purpose of the current class.
General software development is divided into four levels:
@Controller: represents the business logic layer;
@Servie: service layer;
@Repository: persistence layer;
@Configuration: configuration layer;
The above @Component is not within these four layers.
The relationship between class annotations ( Annotations other than @Component annotations are implemented based on @Component. That is to say, @Component is the parent class of all the above annotations .)
Such as @Controller:
Method annotations (annotations acting on methods) @Bean
First recreate a User class:
package com.demo.spring.beans;
public class User {
private int Id;
private String name;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"Id=" + Id +
", name='" + name + '\'' +
'}';
}
}
Create another UserBeans:
1. Add one of the five major categories of annotations to the class
2. Add Bean annotations to the method
Why not just add @Bean annotations, but also need to add class annotations?
In order to improve efficiency, when we add five types of annotations, Spring will scan these annotated classes, which can greatly reduce the scope of scanning, and then scan the methods annotated by @Bean.
package com.demo.spring.beans;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
@Controller
public class UserBeans {
@Bean//方法返回的对象存储在Spring容器
public User user(){
//创建User对象
User user=new User();
//设置属性
user.setId(1);
user.setName("张三");
//返回对象
return user;
}
}
You can also specify the name of the returned object (the original object name is not available after specifying)
@Bean(name = {"userInfo","user2"})
public User user(){
//创建User对象
User user=new User();
//设置属性
user.setId(1);
user.setName("张三");
//返回对象
return user;
}
Get the User object
import com.demo.spring.beans.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
User user= context.getBean("userInfo", User.class);
System.out.println(user.toString());
}
}
Note: After specifying the name of the returned object, the original object name cannot be used. For example, the above can only use userInfo and user2, but not user:
Summarize the usage rules of @Bean annotation:
1. When using the @Bean annotation, it should be used together with the five major types of annotations, so that the return value of the method can be injected into the IoC container
2. If the name attribute of the bean is not specified, the default is the method name. Once specified, the method name cannot be used. A bean can specify multiple names
3. When using @Bean to annotate multiple methods, and when they are beans of the same type, be sure to use the getBean() method in the form of ID+class name, otherwise an error will occur
④ Get the Bean object from Spring (object assembly/object injection)
Three ways of object injection:
1. Attribute injection
2. Construction method injection
3. Setter injection
1. Property injection (@Autowired)
Attribute injection: use the object that needs to be obtained as an attribute of the class
Inject the Service class into the Controller class as follows:
Service class:
package com.demo.spring.beans;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void sayHi(){
System.out.println("Hi UserService");
}
}
Controller class:
package com.demo.spring.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
@Autowired
private UserService userService;
public void sayHi(){
userService.sayHi();
}
}
Startup class:
import com.demo.spring.beans.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App2 {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController= context.getBean(UserController.class);
userController.sayHi();
}
}
2. Construction method injection (officially recommended writing method)
Constructor injection is to implement injection in the constructor of the class:
package com.demo.spring.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController2 {
private UserService userService;
//在构造方法上加@Autowired注解
@Autowired
public UserController2(UserService userService){
this.userService=userService;
}
public void sayHi(){
userService.sayHi();
}
}
App startup class:
import com.demo.spring.beans.UserController2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App3 {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
UserController2 userController2=context.getBean("userController2", UserController2.class);
userController2.sayHi();
}
}
Note: If there is only one construction method, the @Autowired annotation above can be omitted. The official setting is like this. If there are more than one, it cannot be omitted, and the @Autowired annotation can only be on one construction method.
3. Setter injection
Setter injection is similar to the implementation of the Setter method of the property, except that the @Autowired annotation needs to be added when setting the set method
package com.demo.spring.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController3 {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void sayHi(){
userService.sayHi();
}
}
App startup class:
import com.demo.spring.beans.UserController3;
import com.demo.spring.beans.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App4 {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
UserController3 userController3=context.getBean("userController3",UserController3.class);
userController3.sayHi();
}
}
@Resource annotation and its difference from @Autowired
The @Resource annotation is similar to the @Autowired annotation, but they are somewhat different. (Generally still use @Autowired)
1. Different providers
@Resource is an annotation provided by jdk, while @Autowired is provided by Spring
2. Supported injection methods are different
@Autowired supports the above three injection methods, while @Resource does not support constructor injection
3. The supported parameters are different
@Resource supports more parameter settings, such as name and type settings, while @Autowired only supports required parameter settings
The difference between property injection, constructor injection, and Setter injection to obtain beans
①Property injection is easy to use, but it is limited to use in IoC containers. When using attribute injection at the same time, if the bean corresponding to this attribute is not in the container, the writing method of attribute injection will be invalid.
② Constructor injection, security upgrades, good versatility, and support for non-Ioc containers. It ensures that the property has been injected before using other methods of this class (constructor's sake), avoiding NullPointException.
③Setter method injection, the writing method is a bit more complicated, supports non-IoC containers, and has good versatility, suitable for unit testing. Programmers can pass in different parameters by calling the setter method