Spring IoC注解式开发无敌详细(细节丰富)

1. Spring IoC注解式开发

为了进一步,运用注解,这里我们看看下面这个需求。

目前只知道一个包com.rianbowsea 的名字,扫描这个包下所有的类,当这个类上有@Compoent 注解的时候,实例化该对象,然后放到Map集合中。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.rainbowsea;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 使用某个注解的时候,如果注解的属性值是数组,并且数组中只有一个元素,大括号可以省略。
@Target(ElementType.TYPE)
// @Retention 也是一个元注解,用来标注@Component 注解最终保留在class 文件当中,并且可以被反射机制读取
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {

    // 定义注解的属性
    // String 是属性类型
    // value 是属性名
    String value();

}

package com.rainbowsea;


//
//@Component(value = "userBean",属性名 = 属性值,属性名 = 属性值,属性名 = 属性值...)
//@Component(value = "userBean")
// 如果属性名是 value,value 可以省略
@Component("userBean")
public class User {
}

package com.rainbowsea;


@Component("orderBean")
public class Order {
}

在这里插入图片描述

在这里插入图片描述

package com.rainbowsea;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class ComponentScan {

    /*
    目前只知道一个包的名字,扫描这个包下所有的类,当这个类上有@Compoent 注解的时候,
    实例化该对象,然后放到Map集合中
     */
    public static void main(String[] args) {

        //定义一个集合存储其中的实例化对象
        Map<String,Object> beanMap = new HashMap<>();

        String packageName = "com.rainbowsea";
        // 开始扫描程序
        // .这个正则表达式表示任意字母,这里的“.” 必须是一个普通的"."字符,不能是正则表达式中的“.”
        // 在正则表达式当中怎么表示一个普通的"." 字符呢?使用"\",在Java当中一个“/” 要用两个“//” 表示
        String packagePath = packageName.replaceAll("\\.", "/");

        //System.out.println(packagePath);
        // com 是在类的根路径下的一个目录
        //  url 是一个绝对路径
        URL url = ClassLoader.getSystemClassLoader().getResource(packagePath);
        String path = url.getPath();
        //System.out.println(path);

        // 获取一个绝对路径下的所有文件
        File file = new File(path);
        File[] files = file.listFiles();

        Arrays.stream(files).forEach(file1 -> {
            //System.out.println(file1);
            //System.out.println(file1.getName().split("\\.")[0]);
            // 拼接成:全限定类名
            String className = packageName + "." + file1.getName().split("\\.")[0];
            // 再通过反射机制,解析注解
            Class<?> aClass = null;
            try {
                aClass = Class.forName(className);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

            // 判断该类是否含有该 Component.class 注解
            if(aClass.isAnnotationPresent(Component.class)) {
                // 获取注解
                Component annotation = aClass.getAnnotation(Component.class);
                // 获取到该注解的值
                String id = annotation.value();
                // 有这个注解的都要创建对象
                try {
                    Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                    Object obj  = declaredConstructor.newInstance();
                    // 将创建好的实例化对象存储到 Map 当前去。
                    beanMap.put(id,obj);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }

        });


        System.out.println(beanMap);
    }
}

运行结果:

在这里插入图片描述

3. Spring 声明Bean的注解

注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发

在Spring 当中,负责声明 Bean 的注解的,常见的有如下四个:

  • @Compoent

在这里插入图片描述

  • @Controller

在这里插入图片描述

  • @Service

在这里插入图片描述

  • @Repository

在这里插入图片描述

通过源码可以看到,@Controller、@Service、@Repository 这三个注解都是@Component注解的别名。换句话说:这四个注解的功能都一样。用哪个都可以。
只是为了增强程序的可读性,建议:

  • 控制器类上使用:Controller

  • service类上使用:Service

  • dao类上使用:Repository

他们都是只有一个value属性。value属性用来指定bean的id,也就是bean的名字

在这里插入图片描述

3.1 Spring注解的使用

如何使用以上的注解呢?

    • 第一步:加入aop的依赖
    • 第二步:在配置文件中添加context命名空间
    • 第三步:在配置文件中指定扫描的包
    • 第四步:在Bean类上使用注解

第一步:加入aop的依赖

还是第一步,通过Maven 导入相关的 jar 包,在 pom.xml 文件当中。

<?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>com.rainbowsea.reflect</groupId>
    <artifactId>spring6-oo8-anotation-blog</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.11</version>
        </dependency>


        <!-- junit4 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>jakarta.annotation</groupId>
            <artifactId>jakarta.annotation-api</artifactId>
            <version>2.1.1</version>
        </dependency>
    </dependencies>
</project>

我们可以看到当加入spring-context依赖之后,会关联加入aop的依赖。所以这一步不用做。

在这里插入图片描述

第二步:在配置文件中添加context命名空间

注意:这里所说的配置文件是指,我们配置 bean 对象的那个配置.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">

</beans>

第三步:在配置文件中指定扫描的包

注意:这里所说的配置文件是指,我们配置 bean 对象的那个配置.xml 的配置文件信息。如下:

指定扫描的包: 是指明Spring 在那个包路径下,可以找到要实例化的 Bean 对象。

在这里插入图片描述

在这里插入图片描述

<!--    指定扫描的包,-->
    <context:component-scan base-package="com.rainbowsea.reflect.sprint.bean"></context:component-scan>
  • 29
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wx647__et03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值