Spring5学习:IOC容器-Bean管理-3


前言

跟随尚硅谷学习Spring5
IOC容器

一、IOC 操作 Bean 管理(bean 生命周期)

  • 生命周期
    • 从对象创建到对象销毁的过程
  • bean生命周期
    • 通过构造器创建 bean 实例(无参数构造)
    • 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
    • 调用 bean 的初始化的方法(需要进行配置初始化的方法)
    • bean 可以使用了(对象获取到了)
    • 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
  • 演示 bean 生命周期
     创建类,定义属性和对应的 set 方法
package com.atguigu.spring5.dependencyInjection.beanLifeCycle;

public class Orders {

    public Orders() {
        System.out.println("Orders: 第一步 执行无参数构造创建bean实例");
    }

    private String orderName;

    public void setOrderName(String orderName) {
        this.orderName = orderName;
        System.out.println("Orders: 第二步 调用set方法设置属性值");
    }

    @Override
    public String toString() {
        return "Orders{" +
                "orderName='" + orderName + '\'' +
                '}';
    }

    // 创建执行的初始化方法
    public void myCustomInitMethod() {
        System.out.println("Orders: 第三步 调用初始化方法");
    }

    // 创建执行的销毁方法
    public void myCustomDestroyMethod() {
        System.out.println("Orders: 第五步 调用销毁方法");
    }
}

  在 spring配置文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="orders" class="com.atguigu.spring5.dependencyInjection.beanLifeCycle.Orders" init-method="myCustomInitMethod" destroy-method="myCustomDestroyMethod">
        <property name="orderName" value="手机"/>
    </bean>
</beans>

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.beanLifeCycle.Orders;
import com.atguigu.spring5.dependencyInjection.beanLifeCycle.Orders3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeCycleTest {

    @Test
    public void testBeanLifeCycle() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanLifeCycle.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第四步 获取创建的bean实例对象");
        System.out.println(orders);
        // 手动让bean实例销毁,来调用destroy方法
        ((ClassPathXmlApplicationContext) context).close();
    }
}
  • 在bean的基础五步生命周期外,还有额外的两步,bean 的后置处理器, bean 生命周期有七步
    • 通过构造器创建 bean 实例(无参数构造)
    • 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
    • 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
    • 调用 bean 的初始化的方法(需要进行配置初始化的方法)
    • 把 bean 实例传递 bean 后置处理器的方法postProcessAfterInitialization
    • bean 可以使用了(对象获取到了)
    • 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
  • 演示添加后置处理器效果
     创建类,定义属性和对应的 set 方法
package com.atguigu.spring5.dependencyInjection.beanLifeCycle;

public class Orders {

    public Orders() {
        System.out.println("Orders: 第一步 执行无参数构造创建bean实例");
    }

    private String orderName;

    public void setOrderName(String orderName) {
        this.orderName = orderName;
        System.out.println("Orders: 第二步 调用set方法设置属性值");
    }

    @Override
    public String toString() {
        return "Orders{" +
                "orderName='" + orderName + '\'' +
                '}';
    }

    // 创建执行的初始化方法
    public void myCustomInitMethod() {
        System.out.println("Orders: 第三步 调用初始化方法");
    }

    // 创建执行的销毁方法
    public void myCustomDestroyMethod() {
        System.out.println("Orders: 第五步 调用销毁方法");
    }
}
package com.atguigu.spring5.dependencyInjection.beanLifeCycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPost implements BeanPostProcessor {

    // 后置处理器 - 初始化前
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization() - 在bean初始化之前执行的方法");
        return bean;
    }

    // 后置处理器 - 初始化后
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization() - 在bean初始化之后执行的方法");
        return bean;
    }
}

  在 spring配置文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--添加了初始化前后的方法,方法只做打印处理,来测试后置处理器是否正常工作
        以下是bean里面写的打印方法,方法名随意:
            init-method="myCustomInitMethod" destroy-method="myCustomDestroyMethod"
        若不添加上面的init-method和destroy-method,后置处理器同样会作用域该bean
    -->
    <bean id="orders" class="com.atguigu.spring5.dependencyInjection.beanLifeCycle.Orders" init-method="myCustomInitMethod" destroy-method="myCustomDestroyMethod">
        <property name="orderName" value="电脑"/>
    </bean>
    
    <!--myBeanPost的bean实现类,实现了BeanPostProcessor接口,则对于该配置文件的所有bean实例化前后都会执行该实例化前后的后置处理器!-->
    <bean id="myBeanPost" class="com.atguigu.spring5.dependencyInjection.beanLifeCycle.MyBeanPost"/>
</beans>

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.beanLifeCycle.Orders;
import com.atguigu.spring5.dependencyInjection.beanLifeCycle.Orders3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeCycleTest {

        @Test
    public void testBeanLifeCyclePostProcessor() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanLifeCyclePostProcessor.xml");

        /**
         * getBean()方法读取【任意一个】配置文件里的对象,所有配置文件里的对象皆被初始化
         */
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("所有通用:第四步 获取创建的bean实例对象");
        System.out.println(orders);
        // 手动让bean实例销毁,来调用destroy方法
        ((ClassPathXmlApplicationContext) context).close();
    }
}

二、IOC 操作 Bean 管理(xml 自动装配)

 创建类,定义属性和对应的 set 方法

package com.atguigu.spring5.dependencyInjection.autowired;

public class Employee {

    private Department department;

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "department=" + department +
                '}';
    }
}
package com.atguigu.spring5.dependencyInjection.autowired;

public class Department {
}

  在 spring 配置文件中进行配置,对比非自动装配和自动装配

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--非自动装配写法-->
    <!--
    <bean id="dept" class="com.atguigu.spring5.dependencyInjection.autowired.Department"/>

    <bean id="emp" class="com.atguigu.spring5.dependencyInjection.autowired.Employee">
        <property name="department" ref="dept"></property>
    </bean>
    -->


    <!--实现自动装配
        bean标签属性autowire,配置自动装配
        autowire属性常用两个值:
            byName - 根据属性名称注入
            byType - 根据属性类型注入
    -->
    <bean id="dept" class="com.atguigu.spring5.dependencyInjection.autowired.Department"/>

<!--    <bean id="dept2" class="com.atguigu.spring5.dependencyInjection.autowired.Department"/>-->
<!--    <bean id="emp" class="com.atguigu.spring5.dependencyInjection.autowired.Employee" autowire="byName"/>-->
    <bean id="emp" class="com.atguigu.spring5.dependencyInjection.autowired.Employee" autowire="byType"/>
</beans>

  测试:

package com.atguigu.sprint5;
import com.atguigu.spring5.dependencyInjection.autowired.Employee;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanAutowiredTest {

    @Test
    public void testBeanOriginalApproach() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanAutowired.xml");
        Employee emp = context.getBean("emp", Employee.class);
        System.out.println(emp);
    }
}

三、IOC 操作 Bean 管理(外部属性文件)

  • 直接配置数据库信息
      配置德鲁伊连接池
      引入德鲁伊连接池依赖 jar 包
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--直接配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
</beans>
  • 引入外部属性文件配置数据库连接池
      创建外部属性文件, properties格式文件,写数据库信息
jdbc.driverClassName="com.mysql.jdbc.Driver"
jdbc.url="jdbc:mysql://localhost:3306/test"
jdbc.username="root"
jdbc.password="root"
  • 把外部 properties 属性文件引入到 spring 配置文件中
      引入 context 名称空间
      在 spring 配置文件使用标签引入外部属性文件
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
                           
    <!--
        1. 引入外部属性文件,使用引入context命名空间的context标签
        2. 使用${}表达式读取外部属性文件的值
    -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

  测试:

package com.atguigu.sprint5;

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanExternalConfigTest {

    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanDruid.xml");
        DruidDataSource dataSource = context.getBean("dataSource", DruidDataSource.class);
        System.out.println(dataSource);
    }
}

四、IOC 操作 Bean 管理(基于注解方式)

  • 什么是注解
    • 注解是代码特殊标记,格式: @注解名称(属性名称=属性值, 属性名称=属性值…)
    • 使用注解,注解作用在类上面,方法上面,属性上面
    • 使用注解目的:简化 xml 配置
  • Spring 针对 Bean 管理中创建对象提供注解
    • @Component 普通组件
    • @Service 用于业务逻辑层
    • @Controller 用于Web层
    • @Repository 用于Dao层
      上面四个注解功能是一样的,都可以用来创建 bean 实例

 基于注解方式实现对象创建

  引入依赖
  开启组件扫描

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
                           
    <!--开启组件扫面
        方式1:如果扫描多个包, 多个包使用逗号隔开
        方式2:扫描包上层目录
    -->
<!--    <context:component-scan base-package="com.atguigu.spring5.dependencyInjection.annotations.dao, com.atguigu.spring5.dependencyInjection.annotations.service"/>-->
    <context:component-scan base-package="com.atguigu.spring5.dependencyInjection.annotations"/>
</beans>

  在类上面添加创建对象注解

package com.atguigu.spring5.dependencyInjection.annotations.service;

import org.springframework.stereotype.Component;

@Component // 写法1,不加括号内容,默认值类名首字母小写
//@Component(value="userService") // 写法2,等同于<bean id="userService class=".."/>
public class UserService {

    public void add() {
        System.out.println("service add.....");
    }
}

 开启组件扫描细节配置

  扫描哪些类

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启组件扫面:include参数
        use-default-filters="false" - 表示步使用默认filter,自己配置filter
    -->
    <context:component-scan base-package="com.atguigu.spring5.dependencyInjection.annotations" use-default-filters="false">
        <!--只扫描带@Controller的类-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

</beans>

  不扫描哪些类

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启组件扫面:exclude参数-->
    <context:component-scan base-package="com.atguigu.spring5.dependencyInjection.annotations">
        <!--只扫描带@Controller的类-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

 基于注解方式实现属性注入

  • @Autowired:根据属性类型进行自动装配
  • @Qualifier:根据名称进行注入
  • @Resource:可以根据类型注入,可以根据名称注入
  • @Value:注入普通类型属性

  @Autowired:根据属性类型进行自动装配

  把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解

package com.atguigu.spring5.dependencyInjection.annotations.dao;

public interface BookDao {
    public void add();
}
package com.atguigu.spring5.dependencyInjection.annotations.dao;

import org.springframework.stereotype.Repository;

@Repository
public class BookDaoImpl implements BookDao {

    public void add() {
        System.out.println("BookDaoImpl.add() - book dao add...");
    }
}

  在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解

package com.atguigu.spring5.dependencyInjection.annotations.service;

import com.atguigu.spring5.dependencyInjection.annotations.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookServiceAutowired {

    // service上调用dao,需要定义dao类型属性
    // 注意这里不需要添加setter方法
    @Autowired // 根据类型进行注入:byType
    private BookDao bookDao;

    public void add() {
        System.out.println("BookServiceAutowired.add() - book service add.....");
        // 为了体现属性注入效果,在这里打印dao方法
        bookDao.add();
    }
}

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.annotations.service.BookServiceAutowired;
import com.atguigu.spring5.dependencyInjection.annotations.service.UserServiceQualifier;
import com.atguigu.spring5.dependencyInjection.annotations.service.ValueNormalDataInjectionService;
import com.atguigu.spring5.dependencyInjection.annotations.service.WorkerServiceResource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanAnnotationsTest {

    @Test
    public void testAutowired() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanAnnotations.xml");
        BookServiceAutowired bookServiceAutowired = context.getBean("bookServiceAutowired", BookServiceAutowired.class);
        bookServiceAutowired.add();
    }

  @Qualifier:根据名称进行注入

  这个@Qualifier 注解的使用,要上面@Autowired 一起使用

package com.atguigu.spring5.dependencyInjection.annotations.dao;

public interface UserDao {
    public void add();
}

  当一个接口有多个实现类的时候

package com.atguigu.spring5.dependencyInjection.annotations.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {

    public void add() {
        System.out.println("UserDaoImpl.add() - user dao add.....");
    }
}
package com.atguigu.spring5.dependencyInjection.annotations.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {

    public void add() {
        System.out.println("UserDaoImpl.add() - user dao add.....");
    }
}
package com.atguigu.spring5.dependencyInjection.annotations.dao;

import org.springframework.stereotype.Repository;

@Repository(value="userDaoImpl2")
public class UserDaoImpl2 implements UserDao {

    public void add() {
        System.out.println("UserDaoImpl2.add() - user dao add.....");
    }
}

  有多个实现类的时候,指定名称选择对应实现类来注入指定实现类类依赖对象

package com.atguigu.spring5.dependencyInjection.annotations.service;

import com.atguigu.spring5.dependencyInjection.annotations.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class UserServiceQualifier {

    // service上调用dao,需要定义dao类型属性
    // 注意这里不需要添加setter方法
    @Autowired // 根据类型进行注入:byType
    @Qualifier(value="userDaoImpl2") // 假如有多个实现类的时候,指定名称选择对应实现类来注入指定实现类类依赖对象
    private UserDao userDao;

    public void add() {
        System.out.println("UserServiceQualifier.add() - user service add.....");
        // 为了体现属性注入效果,在这里打印dao方法
        userDao.add();
    }
}

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.annotations.service.BookServiceAutowired;
import com.atguigu.spring5.dependencyInjection.annotations.service.UserServiceQualifier;
import com.atguigu.spring5.dependencyInjection.annotations.service.ValueNormalDataInjectionService;
import com.atguigu.spring5.dependencyInjection.annotations.service.WorkerServiceResource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanAnnotationsTest {

    @Test
    public void testQualifier() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanAnnotations.xml");
        UserServiceQualifier userServiceQualifier = context.getBean("userServiceQualifier", UserServiceQualifier.class);
        userServiceQualifier.add();
    }
}

  @Resource:可以根据类型注入,可以根据名称注入

  创建类

package com.atguigu.spring5.dependencyInjection.annotations.dao;

public interface WorkerDao {
    public void add();
}
package com.atguigu.spring5.dependencyInjection.annotations.dao;

import org.springframework.stereotype.Repository;

//@Repository // 根据类型注入
@Repository(value = "workerDaoImpl")  // 根据名称注入
public class WorkerDaoImpl implements WorkerDao{

    public void add() {
        System.out.println("WorkerDaoImpl.add() - worker dao add.....");
    }
}

  使用类型注入和名称注入结果相同

package com.atguigu.spring5.dependencyInjection.annotations.service;

import com.atguigu.spring5.dependencyInjection.annotations.dao.WorkerDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class WorkerServiceResource {

//    @Resource // 根据类型注入
    @Resource(name="workerDaoImpl") // 根据名称注入
    private WorkerDao workerDao;

    public void add() {
        System.out.println("WorkerServiceResource.add() - worker service add.....");
        workerDao.add();
    }
}

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.annotations.service.BookServiceAutowired;
import com.atguigu.spring5.dependencyInjection.annotations.service.UserServiceQualifier;
import com.atguigu.spring5.dependencyInjection.annotations.service.ValueNormalDataInjectionService;
import com.atguigu.spring5.dependencyInjection.annotations.service.WorkerServiceResource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanAnnotationsTest {

    @Test
    public void testResource() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanAnnotations.xml");
        WorkerServiceResource workerServiceResource = context.getBean("workerServiceResource", WorkerServiceResource.class);
        workerServiceResource.add();
    }
}

  @Value:注入普通类型属性

package com.atguigu.spring5.dependencyInjection.annotations.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class ValueNormalDataInjectionService {

    @Value(value = "abc")
    private String str;

    public void valueTest() {
        System.out.println("使用@Value注入的值为:" + str);
    }
}

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.annotations.service.BookServiceAutowired;
import com.atguigu.spring5.dependencyInjection.annotations.service.UserServiceQualifier;
import com.atguigu.spring5.dependencyInjection.annotations.service.ValueNormalDataInjectionService;
import com.atguigu.spring5.dependencyInjection.annotations.service.WorkerServiceResource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanAnnotationsTest {

    @Test
    public void testValue() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beanAnnotations.xml");
        ValueNormalDataInjectionService valueNormalDataInjectionService = context.getBean("valueNormalDataInjectionService", ValueNormalDataInjectionService.class);
        valueNormalDataInjectionService.valueTest();
    }
}

 完全注解开发

  创建配置类,替代xml 配置文件

package com.atguigu.spring5.dependencyInjection.annotations.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration // 作为配置类,替代xml配置文件
/**
 * 开启组件扫面:
 *  方式1:如果扫描多个包, 多个包使用逗号隔开
 *  方式2:扫描包上层目录
 */
//@ComponentScan(basePackages = {"com.atguigu.spring5.dependencyInjection.annotations.dao, com.atguigu.spring5.dependencyInjection.annotations.service"})
@ComponentScan(basePackages = {"com.atguigu.spring5"})
public class SpringConfig {
}

  创建类和接口

package com.atguigu.spring5.dependencyInjection.annotations.dao;

public interface BookDao {
    public void add();
}

  添加创建对象注解

package com.atguigu.spring5.dependencyInjection.annotations.service;

import com.atguigu.spring5.dependencyInjection.annotations.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BookService {

    // service上调用dao,需要定义dao类型属性
    // 注意这里不需要添加setter方法
    @Autowired // 根据类型进行注入:byType
    private BookDao bookDao;

    public void add() {
        System.out.println("BookServiceAutowired.add() - book service add.....");
        // 为了体现属性注入效果,在这里打印dao方法
        bookDao.add();
    }
}

  测试:

package com.atguigu.sprint5;

import com.atguigu.spring5.dependencyInjection.annotations.config.SpringConfig;
import com.atguigu.spring5.dependencyInjection.annotations.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class BeanAnnotationsTest {

    @Test
    public void testAutowired() {
        // 加载配置类
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookService bookService = context.getBean("bookService", BookService.class);
        bookService.add();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值