• 04 Spring 注解实现IOC


    目录

    前言:

    一、准备工作

    二、注解实现IOC_@Component

    三、注解实现IOC_@Repository、@Service、@Controller、@Scope

    四、注解实现IOC_@Autowired

    五、注解实现IOC_@Qualifier

    六、注解实现IOC_@Value

    七、注解实现IOC_@Configuration

    八、注解实现IOC_@ComponentScan

    九、注解实现IOC_@PropertySource

    十、注解实现IOC_@Bean

    十一、注解实现IOC_@Import


    前言:

    注解配置和xml配置对于SpringIOC要实现的功能都是一样的,只是配置的形式不一样。

    一、准备工作

    1.创建一个新的Spring项目。
    2
    2.编写pojodaoservice类。

     3.编写空的配置文件bean.xml,如果想让该文件支持注解,需要添加新的约束:

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:context="http://www.springframework.org/schema/context"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:comtext="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context
    8. http://www.springframework.org/schema/context/spring-context.xsd">
    9. beans>

    二、注解实现IOC_@Component

    作用:用于创建对象,放入Spring容器,相当于

    位置:类上方

    注意:

    1.要在bean.xml配置文件中配置扫描的包,扫描到该注解才能生效。

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:context="http://www.springframework.org/schema/context"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:comtext="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context
    8. http://www.springframework.org/schema/context/spring-context.xsd">
    9. <comtext:component-scan base-package="com.itbaizhan">comtext:component-scan>
    10. beans>

    2.@Component 注解配置bean的默认id是首字母小写的类名。也可以手动设置beanid值。

    1. /**
    2. * @Component 注解相当于bean.xml文件中的标签,创建一个对象并放入容器中
    3. * @Component注解配置bean的默认id是首字母小写的类名,此时bean的id为studentService
    4. */
    5. @Component
    6. public class StudentService {
    7. private StudentDao studentDao;
    8. public Student findStudentById(int id){
    9. return studentDao.findById(id);
    10. }
    11. }
    1. //手动为id赋值,此时bean的id为studentDao
    2. @Component("studentDao")
    3. public class StudentDaoImpl implements StudentDao {
    4. @Override
    5. public Student findById(int id) {
    6. return new Student(1,"程序员","山海");
    7. }
    8. }

    知识点整理:

    1.spring中, @Component 注解代替的是标签“

    2. spring中, @Component 注解中的value属性值表示 “bean对象的id ”

    三、注解实现IOC_@Repository@Service@Controller、@Scope

     作用:这三个注解和@Component的作用一样,使用它们是为了区分该类属于什么层。

    位置:

    (1)@Repository用于Dao层(持久层)

    (2)@Service用于Service层(服务层)

    (3)@Controller用于Controller层(控制层)

    1. @Repository(“studentDao”)
    2. public class StudentDaoImpl implements StudentDao{
    3. }
    1. @Service
    2. public class StudentService {}

    (4)注解实现IOC_@Scope

     作用:指定bean的创建策略

    位置:类上方

    取值:singleton、prototype、request、session、globalsession

    1. @Service
    2. @Scope("singleton")
    3. public class StudentService {}

    知识点整理:

    1. spring 中, @Repository 一般写在类上的“持久层 ”
    2.在 Spring 中, @Scope 的作用是“指定 bean 的创建策略 ”

    四、注解实现IOC_@Autowired

     作用:从容器中查找符合属性类型的对象自动注入属性中,用于代替中的依赖“自动注入”配置

    位置:属性上方/Setter方法上方/构造方法上方

    注意:

    1.@Autowired 写在属性上方进行依赖注入时,可以省略setter方法。

    (1)Service层StudentService

    1. @Component
    2. public class StudentService {
    3.    @Autowired
    4.    private StudentDao studentDao;
    5. public void getStudentDao(){
    6. return StudentDao;
    7. }
    8.    public Student findStudentById(int id) {
    9.        return studentDao.findById(id);
    10.   }
    11. }

    (2)测试方法

    1. @Test
    2. public void t2(){
    3.    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml") ;
    4.    StudentService studentService = (StudentService) ac.getBean("studentService");
    5.   System.out.println(studentService.findStudentById(1));
    6. }

    2.容器中没有对应类型的对象会报错

    1. public class StudentService {
    2. @Autowired
    3. private StudentDao studentDao;
    4. //省略构造方法、Setter、getter方法
    5. }
    1. //@Component("studentDao")
    2. //@Repository("studentDao")
    3. public class StudentDaoImpl implements StudentDao {
    4. @Override
    5. public Student findById(int id) {
    6. return new Student(1,"程序员","山海");
    7. }
    8. }

    如上,StudentService中注入的studentDao,在StudentDao接口的实现类中找不到,所以会报错

    3.容器中有多个对象匹配类型时,会找 等于属性名的对象,找不到会报错

    1. // 如果容器中都多个同类型对象,会根据id值等于属性名找对象
    2. @Component("studentDao")
    3. public class StudentDaoImpl implements StudentDao{
    4.    public Student findById(int id) {
    5.        // 模拟根据id查询学生
    6.        return new Student(1,"百战程序员","北京");
    7.   }
    8. }
    1. @Component
    2. public class StudentDaoImpl2 implements StudentDao{
    3.    public Student findById(int id) {
    4.        // 模拟根据id查询学生
    5.        return new Student(1,"百战程序员","北京");
    6. }
    7. }

    如上,StudentDao接口有两个实现类,如果注解中没有标明value的值对应属性名的话,就会报错。

    知识点整理:

    Spring 中, @Autowired 不能写在“类 ”上方,可以写在“属性”、“setter方法 ”、“构造方法 ”上方

    五、注解实现IOC_@Qualifier

     作用:在按照类型注入对象的基础上,再按照bean的id注入。也就是说先匹配@Qualifier(“”)。

    位置:属性上方

    注意:@Qualifier必须和@Autowired一起使用。

    1. // 如果容器中都多个同类型对象,会根据id值等于属性名找对象
    2. @Component("studentDao")
    3. public class StudentDaoImpl implements StudentDao{
    4.    public Student findById(int id) {
    5.        // 模拟根据id查询学生
    6.        return new Student(1,"百战程序员","北京");
    7.   }
    8. }
    1. @Component
    2. public class StudentDaoImpl2 implements StudentDao{
    3.    public Student findById(int id) {
    4.        // 模拟根据id查询学生
    5.        return new Student(1,"百战程序员","北京");
    6. }
    7. }
    1. @Component
    2. public class StudentService {
    3.    @Autowired
    4.     @Qualifier("studentDaoImpl2")
    5.    private StudentDao studentDao;
    6.    public Student findStudentById(int id){
    7.        return studentDao.findById(id);
    8.   }
    9. }

    如上,注入的是接口StudentDao的实现类StudentDaoImpl2,而不是StudentDaoImpl。因为这里指定了注入实现类StudentDaoImpl2.

    六、注解实现IOC_@Value

     作用:注入String类型和基本数据类型的属性值。

    位置:属性上方

    用法:

    1.直接设置固定的属性值

    1. @Service
    2. public class StudentService {
    3.    @Value("1")
    4.    private int count;
    5.    @Value("hello")
    6.    private String str;
    7. }

    2.获取配置文件中的属性值

    (1)编写配置文件db.properties

    1. jdbc.username=root
    2. jdbc.password=123456

    (2)spring核心配置文件扫描配置文件

    1. <context:property-placeholder location="db.properties">context:property-placeholder>

    (3)注入配置文件中的属性值

    1. @Service
    2. public class StudentService {
    3.   // 基本数据类型
    4. @Value("1")
    5. private int count;
    6. @Value("hello")
    7. private String str;
    8. @Value("${jdbc.username}")
    9. private String username;
    10. @Value("${jdbc.password}")
    11. private String password;
    12. }

    七、注解实现IOC_@Configuration

     上述注解中已经基本解决了大部分的开发,但依然离不开Spring的xml配置文件。接下来将脱离bean.xml,使用纯注解实现IOC。

    在真实开发中,我们一般还是会保留xml配置文件,很多情况下使用配置文件更加方便。
    纯注解实现 IOC 需要一个 Java 类代替 xml 文件。这个 Java类上方需要添加@Configuration,表示该类是一个配置类,作用是代替配置文件。
    1. @Configuration
    2. public class SpringConfig {  
    3. }

    配置文件:

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:context="http://www.springframework.org/schema/context"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:comtext="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context
    8. http://www.springframework.org/schema/context/spring-context.xsd">
    9. <comtext:component-scan base-package="com.itbaizhan">comtext:component-scan>
    10. <context:property-placeholder location="db.properties">context:property-placeholder>
    11. beans>

    八、注解实现IOC_@ComponentScan

    作用:指定spring在初始化容器时扫描的包。

    位置:配置类上方

    九、注解实现IOC_@PropertySource

     作用:代替配置文件中的 -placeholder> 扫描配置文件

    位置:配置类上方
    注意:配置文件位置前要加关键字 classpath
    1. //@Configuration使用类代替配置文件bean.xml
    2. @Configuration
    3. //@ComponentScan指定spring在初始化容器时扫描的包。
    4. @ComponentScan("com.itbaizhan")
    5. //@PropertySource代替配置文件中的 扫描配置文件
    6. @PropertySource("classpath:db.properties")
    7. public class SpringConfig {
    8. }

    十、注解实现IOC_@Bean

    作用:将方法的返回值对象放入Spring容器中,如果想将第三方类的对象放入容器,可以使用@Bean。

    (一般情况下,@Bean就是用来引入那些不能修改源码的类对象,如Spring源码不能添加注解,但要引入其中的类对象,所以用@Bean方式来引入第三方的类对象)

    位置:配置类的方法上方。

    属性:name:给bean对象设置id

    注意:@Bean修饰的方法如有参数,Spring会根据参数类型从容器中查找可用对象。

    举例:如果想将JDBC连接对象放入Spring容器,但我们无法修改Connection源码来添加@Component,此时就需要使用@Bean将该对象放入Spring容器。

    测试步骤:

    (1)添加驱动依赖

    1. <dependency>
    2. <groupId>mysqlgroupId>
    3. <artifactId>mysql-connector-javaartifactId>
    4. <version>8.0.26version>
    5. dependency>

    (2)将Connection对象放入Spring容器

    1. public class SpringConfig {
    2. @Bean(name="connection")
    3. public Connection getConnection(StudentService studentService) {
    4. System.out.println(studentService);
    5. try {
    6. Class.forName("com.mysql.cj.jdbc.Driver");
    7. return DriverManager.getConnection("jdbc:mysql:///mysql","root","123456");
    8. } catch (Exception e) {
    9. return null;
    10. }
    11. }
    12. }

    (3)测试

    1. // 测试@Bean注解
    2. @Test
    3. public void t4(){
    4. // 1.先注册容器,读取SpringConfig类
    5. ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
    6. // 2.创建对象
    7. Connection connection = (Connection) ac.getBean("connection");
    8. System.out.println(connection);
    9. }

    十一、注解实现IOC_@Import

    作用:如果配置过多,会有多个配置类,该注解可以为主配置类导入其他配置类

    位置:主配置类上方

    如:SpringConfig为主配置类、JdbcConfig为配置类

    1. public class JdbcConfig {
    2. // @Bean:引入第三方的类对象
    3. @Bean(name="connection")
    4. public Connection getConnection(StudentService studentService) {
    5. System.out.println(studentService);
    6. try {
    7. Class.forName("com.mysql.cj.jdbc.Driver");
    8. return DriverManager.getConnection("jdbc:mysql:///mysql","root","123456");
    9. } catch (Exception e) {
    10. return null;
    11. }
    12. }
    13. }
    1. //@Configuration使用类代替配置文件bean.xml
    2. @Configuration
    3. //@ComponentScan指定spring在初始化容器时扫描的包。
    4. @ComponentScan("com.itbaizhan")
    5. //@PropertySource代替配置文件中的 扫描配置文件
    6. @PropertySource("classpath:db.properties")
    7. //@Import:为主配置类导入其他配置类,@Import中可以导入多个配置类,原理是数组形式;
    8. // 如:@Import{JdbcConfig.class,StudentDao.class}
    9. @Import(JdbcConfig.class)
    10. public class SpringConfig {
    11. }

  • 相关阅读:
    如何应对数字时代的网络安全新挑战?
    Java实现PDF读取
    Git从入门到起飞(详细)
    Linux nohup 命令
    工作应当有挑战
    面试官:连 INSERT INTO SET 都不知道怎么用,你这3年都干些什么了?
    [SWPU2019]Web1
    JS操作字符串方法学习系列(4)-每天学习10个方法
    杂谈-Android和Ios的对比
    PHP Curl请求封装
  • 原文地址:https://blog.csdn.net/m0_51697147/article/details/126068833