建立 mapper
public interface EmployeeMapper {
void save();
}
建立 mapper 实现类
@Repository
public class EmployeeMapperImpl implements EmployeeMapper {
public void save(){
System.out.println("保存员工信息");
}
}
建立 service
public interface IEmployeeService {
void save();
}
建立 service 实现类
@Service
public class EmployeeServiceImpl implements IEmployeeService {
private EmployeeMapper employeeMapper;
public void setEmployeeMapper(EmployeeMapper employeeMapper){
this.employeeMapper = employeeMapper;
}
public void save() {
employeeMapper.save();
}
}
设置配置类
@Configuration
@ComponentScan("cn.sycoder.di.di01")
public class DiConfig {
}
出现空指针异常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oSHnV3L7-1692700773739)(picture/image-20221028160214170.png)]
@Autowired按照类型注入
通过构造器注入
@Autowired
public EmployeeServiceImpl(EmployeeMapper employeeMapper) {
this.employeeMapper = employeeMapper;
}
通过setter 方法注入
@Autowired
public void setEmployeeMapper(EmployeeMapper employeeMapper) {
this.employeeMapper = employeeMapper;
}
直接在属性上使用(是以后用得最多的)
@Service
public class EmployeeServiceImpl implements IEmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
public void save() {
employeeMapper.save();
}
}
注意:不提供setter 方法以及构造器是使用反射创建对象的
@Test
public void autowired() throws Exception {
final Class<?> aClass = Class.forName("cn.sycoder.di.di01.service.impl.EmployeeServiceImpl");
final Object o = aClass.newInstance();
final Field[] fields = aClass.getDeclaredFields();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DiConfig.class);
final EmployeeMapper bean = context.getBean(EmployeeMapper.class);
for (Field field : fields) {
field.setAccessible(true);
field.set(o,bean);
}
final EmployeeServiceImpl service = (EmployeeServiceImpl) o;
service.save();
}
根据类型注入必须只有一个实现类,否则会报错,添加名称也不行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZJHcdvtU-1692700773741)(picture/image-20221028161616168.png)]
属性required=false,如果找不到不会报错
@Autowired & @Qualifier
@Autowired & @Qualifier必须同时使用,缺一不可
解决刚才出现两个实现类没法注入的问题
配置mapper 并且指定实现类的名称
public interface EmployeeMapper {
void save();
}
@Repository("empMapper2")
public class EmployeeMapperImpl implements EmployeeMapper {
public void save(){
System.out.println("保存员工信息");
}
}
@Repository("empMapper1")
public class EmployeeMapperImpl1 implements EmployeeMapper{
public void save() {
System.out.println("save");
}
}
注入的时候使用名称注入
@Service
public class EmployeeServiceImpl implements IEmployeeService {
@Autowired(required = false)
@Qualifier("empMapper1")
private EmployeeMapper employeeMapper;
public void save() {
employeeMapper.save();
}
}
@Value
@Component
public class DbProperties {
@Value("sy")
private String username;
@Value("123456")
private String password;
}
硬编码,太垃圾了,需要改成动态
@Value
修改配置类
@Configuration
@ComponentScan("cn.sycoder.di.di01")
@PropertySource("db.properties")
public class DiConfig {
}
修改获取方式使用 ${} 的方式
@Component
public class DbProperties {
@Value("${username}")
private String username;
@Value("${password}")
private String password;
public void test(){
System.out.println(username + ":" + password);
}
}
@PropertySource 加载配置文件
位置:配置类上
作用导入配置文件
对于多个配置文件
@Configuration
@ComponentScan("cn.sycoder.di.di01")
@PropertySource({"db.properties","xx.properties"})
public class DiConfig {
}
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
先添加配置类 SpringConfig
@Configuration
public class SpringConfig {
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername("root");
source.setPassword("123456");
source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setUrl("jdbc:mysql://localhost:3306/mybatis");
return source;
}
}
传统做法存在硬编码,DataSource 并且没有交给 spring 管理,每次都需要重新新建 DataSource ,并不存在单例一说
@Test
public void testDruid(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
final SpringConfig bean = context.getBean(SpringConfig.class);
System.out.println(bean.dataSource());
}
使用@Bean 交给 spring 管理
@Configuration
public class SpringConfig {
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername("root");
source.setPassword("123456");
source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setUrl("jdbc:mysql://localhost:3306/mybatis");
return source;
}
}
修改配置的硬编码改成软编码
@Configuration
@PropertySource("druidDb.properties")
public class SpringConfig {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
@Bean 与 xml 对应
@Component
@Component
public class DruidConfig {
@Value("{jdbc.username}")
private String username;
@Value("{jdbc.password}")
private String password;
@Value("{jdbc.url}")
private String url;
@Value("{jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
修改druidConfig
@Configuration
public class DruidConfig {
@Value("{jdbc.username}")
private String username;
@Value("{jdbc.password}")
private String password;
@Value("{jdbc.url}")
private String url;
@Value("{jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
修改spring配置类
@Configuration
@PropertySource("druidDb.properties")
@Import({DruidConfig.class})
public class SpringConfig {
}
如果需要传参,只需要将参数交给spring管理就行了
@Configuration
public class RepositoryConfig {
@Bean
public AccountRepository accountRepository(DataSource dataSource) {
return new JdbcAccountRepository(dataSource);
}
}
注解配置 | xml 配置 | 功能说明 |
---|---|---|
@Component @Controller @Service @Repository |
bean 标签(id,class) | 定义bean |
@ComponentScan | 扫描包加载bean | |
@Autowired @Qualifier @Value |
setter 注入 构造器注入 自动装配 |
依赖注入 |
@Bean | bean 标签,静态工厂模式,实例工厂模式,FactoryBean | 配置第三方bean |
@Scope | bean 标签中的 scope 属性 | 设置作用域 |
@PostConstructor @PreDestroy |
bean 标签中的 init-method / destroy-method | 生命周期相关 |
@Import | 导入其它的配置类 | |
@PropertySource({“db.properties”,“xx.properties”}) | 导入配置文件 |