@Component、@Configuration、@ComponentScan、@Autowired、@Scope、@Value、@Resource、@Bean、@Qualifier、@PropertySource等注解
1. 注解和配置文件applicationContext.xml配合使用
现在有一个接口类Book3Dao、和其实现类Book3DaoImpl,利用注解和配置文件在测试类上调用其下的save方法。
 Book3Dao
package com.bh.dao;
public interface Book3Dao {
    void save();
}
Book3DaoImpl
package com.bh.dao.Impl;
import com.bh.dao.Book3Dao;
@Component(value = "bookDao_1")
public class Book3DaoImpl implements Book3Dao {
    public void save() {
        System.out.println("已保存数据。。 Book3DaoImpl");
    }
}
【注】:Component里可以写value属性值,也可以不写,写上之后在测试类获取这个bean,就可以使用方法getBean(value属性值)获取Bean;否则只能通过getBean(Book3Dao.class)获取。
 applicationContext.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
">  
  
    <context:component-scan base-package="com.bh"/>
	    
</beans>
文件结构
 
测试代码
package com.bh;
import com.bh.dao.Book3Dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test3 {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book3Dao bookDao_1 = ctx.getBean("bookDao_1", Book3Dao.class);
        bookDao_1.save();
    }
}
运行结果:
 
 上面这种实现方式还需要配合配置文件applicationContext.xml一起使用才能运行出结果,下面使用纯注解开发模式,实现上述效果。【注】:记得把这个注释掉。
 
2. 纯注解开发模式
不使用配置文件applicationContext.xml,需要一个Java配置类进行代替。
 SpringConfig配置类
package com.bh.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.bh")
public class SpringConfig {
}
测试代码
package com.bh;
import com.bh.config.SpringConfig;
import com.bh.dao.Book3Dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test3 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        Book3Dao bookDao_1 = ctx.getBean("bookDao_1", Book3Dao.class);
        bookDao_1.save();
    }
}
注意观察这个测试代码和上面那个测试代码之间的不同,运行结果和上述一致。
 关于Bean的单例和非单例设置,在Java类上加注解==@Scope==,并设置值singleton或prototype,前者为单例,后者为非单例,如下:
 

 

3. 使用注解自动装配
现在在2的基础上新建接口Book3Service和其实现类Book3ServiceImpl,在Book3ServiceImpl类中使用自动装配的方式,从而使Book3Dao对象进行注入,如下:
 Book3Service
package com.bh.service;
public interface Book3Service {
    void save();
}
Book3ServiceImpl
package com.bh.service.Impl;
import com.bh.dao.Book3Dao;
import com.bh.service.Book3Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Book3ServiceImpl implements Book3Service {
    @Autowired
    private Book3Dao book3Dao;
    public void save() {
        book3Dao.save();
    }
}
运行结果:
 
 现在如果我新建一个java类Book4DaoImpl,让其实现Book3Dao接口(一般不会出现这种),如下:
 Book4DaoImpl
package com.bh.dao.Impl;
import com.bh.dao.Book3Dao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")  // 非单例
public class Book4DaoImpl implements Book3Dao {
    public void save() {
        System.out.println("已保存数据。。 Book4DaoImpl");
    }
}
之后再运行,就会出现报错,因为我这里定义了两个Book3Dao的bean,spring不知道是哪一个bean。
 
 报错信息为:
 No qualifying bean of type ‘com.bh.dao.Book3Dao’ available: expected single matching bean but found 2: book3DaoImpl,book4DaoImpl
解决办法就是再加一个注解@Qualifier,并设置其value值,如下:
 
 此时运行没有问题,也可以使用注解@Resource,并设置其name值,如下:
 
 此时运行也是没有问题的。需要注意的是@Qualifier需要和@Autowired注解一起使用才行。
4. 第三方bean的定义
现在定义一个DruidDataSource的bean,直接再配置类上进行定义即可,如下:
 SpringConfig
package com.bh.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@ComponentScan("com.bh")
public class SpringConfig {
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc::mysql://localhost:3306/d_test");
        ds.setUsername("root");
        ds.setPassword("sxx123");
        return ds;
    }
}
测试代码
package com.bh;
import com.bh.config.SpringConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import javax.sql.DataSource;
public class Test3 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource bean = ctx.getBean(DataSource.class);
        System.out.println(bean);
    }
}
如果想读取properties文件相关配置信息,可以在Java配置类上加上@PropertySource注解,用来读取指定的peroperties文件,然后使用@Value注解进行占位符注入数据即可,如下:
 jdbc.properties
 
 SpringConfig
package com.bh.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@Configuration
@ComponentScan("com.bh")
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        System.out.println(driverClassName);
        System.out.println(url);
        System.out.println(userName);
        System.out.println(password);
        return ds;
    }
}
运行结果:
 



















