目录
三、注解实现IOC_@Repository、@Service、@Controller、@Scope
前言:
注解配置和xml配置对于Spring的IOC要实现的功能都是一样的,只是配置的形式不一样。
一、准备工作
1.创建一个新的Spring项目。22.编写pojo,dao,service类。3.编写空的配置文件bean.xml,如果想让该文件支持注解,需要添加新的约束:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:comtext="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"> </beans>
二、注解实现IOC_@Component
作用:用于创建对象,放入Spring容器,相当于<bean id="" class="">
位置:类上方
注意:
1.要在bean.xml配置文件中配置扫描的包,扫描到该注解才能生效。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:comtext="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"> <!-- 扫描包,为包下的所有类配置扫描包,扫描到该注解才能生效 --> <comtext:component-scan base-package="com.itbaizhan"></comtext:component-scan> </beans>
2.@Component 注解配置bean的默认id是首字母小写的类名。也可以手动设置bean的id值。
/** * @Component 注解相当于bean.xml文件中的<bean>标签,创建一个对象并放入容器中 * @Component注解配置bean的默认id是首字母小写的类名,此时bean的id为studentService */ @Component public class StudentService { private StudentDao studentDao; public Student findStudentById(int id){ return studentDao.findById(id); } }
//手动为id赋值,此时bean的id为studentDao @Component("studentDao") public class StudentDaoImpl implements StudentDao { @Override public Student findById(int id) { return new Student(1,"程序员","山海"); } }
知识点整理:
1.在spring中, @Component 注解代替的是标签“<bean> ”
2. 在spring中, @Component 注解中的value属性值表示 “bean对象的id ”
三、注解实现IOC_@Repository、@Service、@Controller、@Scope
作用:这三个注解和@Component的作用一样,使用它们是为了区分该类属于什么层。
位置:
(1)@Repository用于Dao层(持久层)
(2)@Service用于Service层(服务层)
(3)@Controller用于Controller层(控制层)
@Repository(“studentDao”) public class StudentDaoImpl implements StudentDao{ }
@Service public class StudentService {}
(4)注解实现IOC_@Scope
作用:指定bean的创建策略
位置:类上方
取值:singleton、prototype、request、session、globalsession
@Service @Scope("singleton") public class StudentService {}
知识点整理:
1. 在 spring 中, @Repository 一般写在类上的“持久层 ”2.在 Spring 中, @Scope 的作用是“指定 bean 的创建策略 ”
四、注解实现IOC_@Autowired
作用:从容器中查找符合属性类型的对象自动注入属性中,用于代替<bean>中的依赖“自动注入”配置
位置:属性上方/Setter方法上方/构造方法上方
注意:
1.@Autowired 写在属性上方进行依赖注入时,可以省略setter方法。
(1)Service层StudentService
@Component public class StudentService { @Autowired private StudentDao studentDao; public void getStudentDao(){ return StudentDao; } public Student findStudentById(int id) { return studentDao.findById(id); } }
(2)测试方法
@Test public void t2(){ ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml") ; StudentService studentService = (StudentService) ac.getBean("studentService"); System.out.println(studentService.findStudentById(1)); }
2.容器中没有对应类型的对象会报错
public class StudentService { @Autowired private StudentDao studentDao; //省略构造方法、Setter、getter方法 }
//@Component("studentDao") //@Repository("studentDao") public class StudentDaoImpl implements StudentDao { @Override public Student findById(int id) { return new Student(1,"程序员","山海"); } }
如上,StudentService中注入的studentDao,在StudentDao接口的实现类中找不到,所以会报错
3.容器中有多个对象匹配类型时,会找<bean id=""> 等于属性名的对象,找不到会报错
// 如果容器中都多个同类型对象,会根据id值等于属性名找对象 @Component("studentDao") public class StudentDaoImpl implements StudentDao{ public Student findById(int id) { // 模拟根据id查询学生 return new Student(1,"百战程序员","北京"); } }
@Component public class StudentDaoImpl2 implements StudentDao{ public Student findById(int id) { // 模拟根据id查询学生 return new Student(1,"百战程序员","北京"); } }
如上,StudentDao接口有两个实现类,如果注解中没有标明value的值对应属性名的话,就会报错。
知识点整理:
五、注解实现IOC_@Qualifier
作用:在按照类型注入对象的基础上,再按照bean的id注入。也就是说先匹配@Qualifier(“”)。
位置:属性上方
注意:@Qualifier必须和@Autowired一起使用。
// 如果容器中都多个同类型对象,会根据id值等于属性名找对象 @Component("studentDao") public class StudentDaoImpl implements StudentDao{ public Student findById(int id) { // 模拟根据id查询学生 return new Student(1,"百战程序员","北京"); } }
@Component public class StudentDaoImpl2 implements StudentDao{ public Student findById(int id) { // 模拟根据id查询学生 return new Student(1,"百战程序员","北京"); } }
@Component public class StudentService { @Autowired @Qualifier("studentDaoImpl2") private StudentDao studentDao; public Student findStudentById(int id){ return studentDao.findById(id); } }
如上,注入的是接口StudentDao的实现类StudentDaoImpl2,而不是StudentDaoImpl。因为这里指定了注入实现类StudentDaoImpl2.
六、注解实现IOC_@Value
作用:注入String类型和基本数据类型的属性值。
位置:属性上方
用法:
1.直接设置固定的属性值
@Service public class StudentService { @Value("1") private int count; @Value("hello") private String str; }
2.获取配置文件中的属性值
(1)编写配置文件db.properties
jdbc.username=root jdbc.password=123456
(2)spring核心配置文件扫描配置文件
<!-- 扫描配置文件 --> <context:property-placeholder location="db.properties"></context:property-placeholder>
(3)注入配置文件中的属性值
@Service public class StudentService { // 基本数据类型 @Value("1") private int count; @Value("hello") private String str; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; }
七、注解实现IOC_@Configuration
上述注解中已经基本解决了大部分的开发,但依然离不开Spring的xml配置文件。接下来将脱离bean.xml,使用纯注解实现IOC。
在真实开发中,我们一般还是会保留xml配置文件,很多情况下使用配置文件更加方便。纯注解实现 IOC 需要一个 Java 类代替 xml 文件。这个 Java类上方需要添加@Configuration,表示该类是一个配置类,作用是代替配置文件。@Configuration public class SpringConfig { }
配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:comtext="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"> <!-- 扫描包,为包下的所有类配置扫描包,扫描到该注解才能生效 --> <comtext:component-scan base-package="com.itbaizhan"></comtext:component-scan> <!-- 扫描配置文件 --> <context:property-placeholder location="db.properties"></context:property-placeholder> </beans>
八、注解实现IOC_@ComponentScan
作用:指定spring在初始化容器时扫描的包。
位置:配置类上方
九、注解实现IOC_@PropertySource
作用:代替配置文件中的 <context:property-placeholder> 扫描配置文件
位置:配置类上方注意:配置文件位置前要加关键字 classpath//@Configuration使用类代替配置文件bean.xml @Configuration //@ComponentScan指定spring在初始化容器时扫描的包。 @ComponentScan("com.itbaizhan") //@PropertySource代替配置文件中的 <context:property-placeholder> 扫描配置文件 @PropertySource("classpath:db.properties") public class SpringConfig { }
十、注解实现IOC_@Bean
作用:将方法的返回值对象放入Spring容器中,如果想将第三方类的对象放入容器,可以使用@Bean。
(一般情况下,@Bean就是用来引入那些不能修改源码的类对象,如Spring源码不能添加注解,但要引入其中的类对象,所以用@Bean方式来引入第三方的类对象)
位置:配置类的方法上方。
属性:name:给bean对象设置id
注意:@Bean修饰的方法如有参数,Spring会根据参数类型从容器中查找可用对象。
举例:如果想将JDBC连接对象放入Spring容器,但我们无法修改Connection源码来添加@Component,此时就需要使用@Bean将该对象放入Spring容器。
测试步骤:
(1)添加驱动依赖
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
(2)将Connection对象放入Spring容器
public class SpringConfig {
@Bean(name="connection")
public Connection getConnection(StudentService studentService) {
System.out.println(studentService);
try {
Class.forName("com.mysql.cj.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql:///mysql","root","123456");
} catch (Exception e) {
return null;
}
}
}
(3)测试
// 测试@Bean注解
@Test
public void t4(){
// 1.先注册容器,读取SpringConfig类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
// 2.创建对象
Connection connection = (Connection) ac.getBean("connection");
System.out.println(connection);
}
十一、注解实现IOC_@Import
作用:如果配置过多,会有多个配置类,该注解可以为主配置类导入其他配置类
位置:主配置类上方
如:SpringConfig为主配置类、JdbcConfig为配置类
public class JdbcConfig {
// @Bean:引入第三方的类对象
@Bean(name="connection")
public Connection getConnection(StudentService studentService) {
System.out.println(studentService);
try {
Class.forName("com.mysql.cj.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql:///mysql","root","123456");
} catch (Exception e) {
return null;
}
}
}
//@Configuration使用类代替配置文件bean.xml
@Configuration
//@ComponentScan指定spring在初始化容器时扫描的包。
@ComponentScan("com.itbaizhan")
//@PropertySource代替配置文件中的 <context:property-placeholder> 扫描配置文件
@PropertySource("classpath:db.properties")
//@Import:为主配置类导入其他配置类,@Import中可以导入多个配置类,原理是数组形式;
// 如:@Import{JdbcConfig.class,StudentDao.class}
@Import(JdbcConfig.class)
public class SpringConfig {
}