目 录
在前面的内容中,如果要使用 bean,总免不了先创建一个 xml 文件,然后写一堆 bean 的标签配置,然后才能使用代码获取要用的 bean,再进行业务逻辑处理。
下面我们在 Spring 中使用注解进行开发,脱离 xml 文件,废话不多说,先来新建一个项目。
1. 新建项目
1.1 开发环境
- IDEA
- Spring 5.3.20
- maven 3.6.3
使用 maven 新建一个 module ,名称是 02-spring-annotation-development,接着新建各个目录和文件,整个项目结构如下所示
1.2 各个目录文件内容
pom.xml 文件
- 父 pom 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.yuhuofei</groupId>
<artifactId>spring-study</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>01-spring-ioc</module>
<module>02-spring-annotation-development</module>
</modules>
<dependencies>
<!--引入spring框架依赖包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
<type>pom</type>
</dependency>
<!--引入jdbc依赖包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
</dependencies>
</project>
- 子 pom 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-study</artifactId>
<groupId>org.yuhuofei</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>02-spring-annotation-development</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
config 配置
- MyConfig.java
package com.yuhuofei.config;
import com.yuhuofei.pojo.Student;
import com.yuhuofei.service.CourseForStudent;
import com.yuhuofei.service.CourseForStudentImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Description
* @ClassName MyConfig
* @Author yuhuofei
* @Date 2022/6/26 23:40
* @Version 1.0
*/
@Configuration
@ComponentScan("com.yuhuofei")
public class MyConfig {
@Bean
public Student getStudent(){
return new Student();
}
@Bean
public CourseForStudent getCourseForStudent(){
return new CourseForStudentImpl();
}
@Bean("controllerUse")
public CourseForStudent getControllerUse(){
return new CourseForStudentImpl();
}
}
controller
- CourseForStudentController.java
package com.yuhuofei.controller;
import com.yuhuofei.service.CourseForStudent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Description
* @ClassName CourseForStudent
* @Author yuhuofei
* @Date 2022/6/26 23:52
* @Version 1.0
*/
@Controller
public class CourseForStudentController {
@Qualifier("controllerUse")
@Autowired
private CourseForStudent courseForStudent;
@RequestMapping("/getStudent")
public void getStudent() {
courseForStudent.getStudent();
}
}
dao
- StudentDao.java
package com.yuhuofei.dao;
/**
* @Description
* @InterfaceName CourseForStudent
* @Author yuhuofei
* @Date 2022/6/26 23:47
* @Version 1.0
*/
public interface StudentDao {
void queryStudent();
}
- StudentDaoImpl.java
package com.yuhuofei.dao;
import org.springframework.stereotype.Repository;
/**
* @Description
* @ClassName CourseForStudentImpl
* @Author yuhuofei
* @Date 2022/6/26 23:48
* @Version 1.0
*/
@Repository
public class StudentDaoImpl implements StudentDao {
@Override
public void queryStudent() {
System.out.println("测试获取学生信息的方法!");
}
}
pojo
- Student.java
package com.yuhuofei.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @Description
* @ClassName Teacher
* @Author yuhuofei
* @Date 2022/6/26 23:42
* @Version 1.0
*/
@Component
public class Student {
@Value("小李")
private String studentName;
@Value("16")
private int studentAge;
@Value("高中物理")
private String course;
@Override
public String toString() {
return "Student{" +
"studentName='" + studentName + '\'' +
", studentAge=" + studentAge +
", course='" + course + '\'' +
'}';
}
}
service
- CourseForStudent.java
package com.yuhuofei.service;
/**
* @Description
* @InterfaceName CourseForStudent
* @Author yuhuofei
* @Date 2022/6/26 23:50
* @Version 1.0
*/
public interface CourseForStudent {
void getStudent();
}
- CourseForStudentImpl.java
package com.yuhuofei.service;
import com.yuhuofei.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description
* @ClassName CourseForStudentImpl
* @Author yuhuofei
* @Date 2022/6/26 23:50
* @Version 1.0
*/
@Service
public class CourseForStudentImpl implements CourseForStudent {
@Autowired
private StudentDao student;
@Override
public void getStudent() {
student.queryStudent();
}
}
test
- MyTest.java
import com.yuhuofei.config.MyConfig;
import com.yuhuofei.pojo.Student;
import com.yuhuofei.service.CourseForStudentImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @Description
* @ClassName MyTest
* @Author yuhuofei
* @Date 2022/6/26 23:39
* @Version 1.0
*/
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Student student = context.getBean("getStudent", Student.class);
System.out.println(student);
System.out.println("===================分隔线======================");
CourseForStudentImpl student1 = context.getBean("getCourseForStudent", CourseForStudentImpl.class);
student1.getStudent();
}
}
1.3 运行测试方法
运行测试类中的 main 方法,得到的结果,如下所示,正确的输出了在代码中指定的内容
2. 内容分析
在上面的项目中,可以看到,没有一个注册 bean 的 xml 文件,这说明上面的项目,完全脱离了之前的配置方式,达到了使用注解开发的目的。虽然形式变了,但是主要的内容,却是一样的。
2.1 配置形式的改变
之前,如果我们需要使用 bean,会先在一个 beans.xml 文件中使用 bean 的标签,配置一个 bean ,然后再获取它来使用。
现在,去掉了 xml 文件的配置,改成直接在 MyConfig.java 这个类中,进行 bean 的配置。这个类中用到的三个注解,非常重要,它们决定了能否生成 bean 并托管给 Spring。
- @Configuration
- @ComponentScan(“com.yuhuofei”)
- @Bean
@Configuration 表示,这是一个配置类,类似于新建的一个 beans.xml 文件
@ComponentScan(“com.yuhuofei”) 表示,要扫描加载 com.yuhuofei 这个目录下的类,如果不是这个目录下的类,不加载,只有被扫描到,类里面的注解才会生效
@Bean 表示,这是一个 bean,配置一个 bean ,类似于之前在 beans.xml 文件中写一个 <bean id="student" class="com.yuhuofei.pojo.Student"/>
2.2 注解的说明
2.2.1 @Component 的衍生注解
- @Controller
- @Repository
- @Service
上面三个都是 @Component 的衍生注解,只不过由于在 web 开发中,开发人员喜欢按照 mvc 三层架构进行分层,每一层用不同名称的注解,标注到一个类上,利于区分。
- dao层:@Repository
- service层:@Service
- Controller层:@Controller
虽然名称不同,但是 @Component 、@Controller、 @Repository、@Service,这四个注解的功能都是一样的,都是表示将某个类注册到 Spring 中,并装配 bean。
2.2.2 项目中的其它注解
- @Value
- @Override
- @RequestMapping
- @Autowired
- @Qualifier
@Value 用于属性注入,如上面的 Student.java 类中使用 @Value(“小李”) 将学生名字注入到studentName 这个属性中。
@Override 用于方法重写,表示子类确定重写了父类的方法。
@RequestMapping 用于启动服务后,对外暴露方法或者说接口的请求路径,例如 @RequestMapping(“/getStudent”),告诉外部,请求 localhost:8080/getStudent ,就能调用到 public void getStudent() 方法。
另外的两个,之前的博文有提及,这里不再赘述。
3. 总结
xml 与注解
- xml 更加万能,适用于任何场合,维护简单方便
- 注解,不是自己的类,使用不了,维护相对复杂
xml 与 注解 实践经验
- xml 更多是用来管理 bean
- 注解更多是用来完成属性的注入
注意点
在使用过程中,要使注解生效,就要开启注解的支持,一个是指定扫描的包路径,另外一个是注解配置
- 如果是使用 xml 文件
<context:component-scan base-package="com.yuhuofei"/>
<context:annotation-config/>
- 如果是使用配置类
@Configuration
@ComponentScan("com.yuhuofei")