Spring IoC容器通过注解方式管理Bean

175 阅读4分钟

实验一:Bean注解标记和扫描(IoC)

如何标记注解

注解说明
@Component该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。
@Repository该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。

对于Spring使用IOC容器管理这些组件来说没有区别,也就是语法层面没有区别。所以@Controller、@Service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辨组件的作用。

注意:虽然它们本质上一样,但是为了代码的可读性、程序结构严谨!我们肯定不能随便胡乱标记。

@Component // <bean id="CommonComponent" class="CommonComponent"/>
public class CommonComponent {}
@Controller
public class XxxController {}
@Service
public class XxxService {}
@Repository
public class XxxDao {}

如何配置文件指定扫描范围,去扫描被标记的注解

   <!-- 1.普通配置包扫描
            base-package 指定ioc容器去哪些包下查找注解类
            可以多个包连在一起标识 base-package="包1,包2"
            指定包将会扫描子包内的所有类
    -->
    <context:component-scan base-package="com.atguigu.ioc_01"/>
    
    <!-- 2/指定不扫描的组件 -->
    <context:component-scan base-package="com.atguigu.ioc_01">

        <!-- context:exclude-filter标签:指定排除规则 -->
        <!-- type属性:指定根据什么来进行排除,annotation取值表示根据注解来排除 -->
        <!-- expression属性:指定排除规则的表达式,对于注解来说指定全类名即可 -->
        <context:exclude-filter type="annotation"
          expression="org.springframework.stereotype.Controller"/>
        <context:exclude-filter type="annotation"
          expression="org.springframework.stereotype.Service"/>
      
    </context:component-scan>
    
    <!-- 3.仅扫描指定的组件 -->
    <!-- 仅扫描 = 关闭默认规则 + 追加规则 -->
    <!-- use-default-filters属性:取值false表示关闭默认扫描规则(将包下的全部包都扫描) -->
    <context:component-scan base-package="com.atguigu.ioc_01"
        use-default-filters="false">

        <!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 -->
        <context:include-filter type="annotation"
          expression="org.springframework.stereotype.Controller"/>
      
    </context:component-scan>

实验二:使用注解进行DI注入 (@Autowired)

//接口设置方法
public interface SoldierService {
    public void getMessage();
}
//两个实体类 连接 接口
@Component
public class maomao1 implements SoldierService{
    @Override
    public void getMessage(){
        System.out.println("maomao1");
    }
}
@Component
public class maomao2 implements SoldierService{
    @Override
    public void getMessage(){
        System.out.println("maomao2");
    }
}

/*@Autowired注解 重点!!!
在成员变量上直接标记@Autowired注解即可,不需要提供setXxx()方法。
以后我们在项目中的正式用法就是这样。*/

//实现实体类
@Service
public class SoldierController {
    //连接接口的实体类被实例化的数量超过1个需要标明 value、
    //方法一:
    @Autowired
    @Qualifier("maomao1") 
    private SoldierService soldierService1;
    //方法二:
    //@Resource(name='maomao2') == @Autowired + @Qualifier(value='maomao2')
    @Resource(name = "maomao2")
    private SoldierService soldierService2;

    public void getMessage() {
        soldierService1.getMessage();
        soldierService2.getMessage();
    }
}

声明与Test都和之前的操作相同

<context:component-scan base-package="com.atguigu.ioc_02" />
@Test
public void testIoc_02(){
    //1.创建ioc容器
    ClassPathXmlApplicationContext applicationContext =
    new ClassPathXmlApplicationContext("spring-02.xml");
    //2.获取组件
    SoldierController bean =
    applicationContext.getBean(SoldierController.class);
    bean.getMessage();
}

使用 @Resource

【高于JDK11或低于JDK8需要引入以下依赖】

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

通过注解+xml配置jdbc实现数据库的查询

父项目所需要的依赖项

<dependencies>
        <!--spring context依赖-->
        <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.6</version>
        </dependency>

        <!--junit5测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>

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

        <!-- spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>6.0.6</version>
        </dependency>
    </dependencies>

完成类的配置

构建一个dao类的接口以及实现类

public interface StudentDao {

    List<Student> queryAll();
}

@Repository
public class StudentDaoIMpl implements StudentDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public List<Student> queryAll(){
        String sql = "select * from students";
        List<Student> studentList =
                jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));
        return studentList;
    }
}

构建一个service类的接口以及实现类

public interface StudentService {
    List<Student> findAll();
}

@Service
public class StudentServiceIMpl implements StudentService {

    @Autowired
    private StudentDao studentDao;
    @Override
    public List<Student> findAll() {
        List<Student> studentList = studentDao.queryAll();
        return studentList;
    }
}

构建一个Controller类的实现类(一般没有接口)

@Controller
public class StudentController {
    
    @Autowired
    private StudentService studentService;
    public void findAll(){
        List<Student> all = studentService.findAll();
        for(int i=0;i<all.size();i++){
            System.out.println(all.get(i));
        }
    }
}

配置jdbc信息以及xml信息

1.配置jdbc

atguigu.url=jdbc:mysql://localhost:3306/studb //studb是数据库名
atguigu.driver=com.mysql.cj.jdbc.Driver
atguigu.username=root
atguigu.password=root

2.配置spring-04.xml

    <!-- 扫描 组件标记-->
    <context:component-scan base-package="com.atguigu"/>

    <!-- 扫描 jdbc配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 为Druid导入 jdbc配置文件,并实例化-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${atguigu.url}"/>
        <property name="driverClassName" value="${atguigu.driver}"/>
        <property name="username" value="${atguigu.username}"/>
        <property name="password" value="${atguigu.password}"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

添加测试类

 @Test
    public void test(){
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-04.xml");
        StudentController bean =
                applicationContext.getBean(StudentController.class);
        bean.findAll();
    }