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,如果想让该文件支持注解,需要添加新的约束:

<?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是首字母小写的类名。也可以手动设置beanid值。

/**
 * @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的值对应属性名的话,就会报错。

知识点整理:

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

五、注解实现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 {
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值