spring 详解五 IOC(注解开发)

spring注解开发

注解开发已经成为开发的主流选择,例如springboot都是基于注解开发使用的spring,所以学习注解开发是很有必要的,基本Bean注解,主要是使用注解的方式替代原有xml的 标签及其标签属性的配置


注解开发之Bean配置

XML 配置 注解 描述
@Component 被该注解标识的类,会在指定扫描范围内被Spring加载并实例化
@Scope 在类上或使用了@Bean标注的方法上,标注Bean的作用范围,取值为singleton或prototype
@Lazy 在类上或使用了@Bean标注的方法上,标注Bean是否延迟加载,取值为true和false
@PostConstruct 在方法上使用,标注Bean的实例化后执行的方法
@PreDestroy 在方法上使用,标注Bean的销毁前执行方法
@Component("userDao")
@Scope("singleton")
@Lazy(true)
public class UserServiceImpl implements UserService{
   @PostConstruct
   public void init(){}
    
   @PreDestroy
   public void destroy(){}
}

配置spring扫描范围



    
    
    

@Component的衍生注解

注解 说明
@Controller 标注在控制器 
@Service 标注在业务类上 
@Repository 标注在数据访问类上

其效果与@Component一致,在其注解内部提供了别名@AliasFor别名注解,@Controller就和@Component的作用一致


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

注解开发之依赖注入配置

之前的xml配置方式


   
   

注解配置 

注解 描述
@Value 使用在字段或方法上,用于注入普通数据
@Autowired   使用在字段或方法上,用于根据类型(byType)注入引用数据
@Qualifier 使用在字段或方法上,结合@Autowired,根据名称注入
@Resource 使用在字段或方法上,根据类型或名称进行注入

@Value

@Value("test")
private String username;

@Value("test")
public void setUsername(String username){
    System.out.println(username);
}

springBoot中读取配置文件

@Value("${jdbc.username: "test"}")
private String username;

@Value("${jdbc.username: "test"}")
public void setUsername(String username){
    System.out.println(username);
}

springBoot 读取配置文件时一定要注意,最好加上默认值,以免报错 

 @Autowired  

//使用在属性上直接注入
@Autowired
private UserDao userDao;

//使用在方法上直接注入
@Autowired
public void setUserDao(UserDao userDao){
      System.out.println(userDao);
}

@Resource 

@Resource
private UserDao userDao;

@Resource(name = "userDao2")
public void setUserDao(UserDao userDao){
    System.out.println(userDao);
}

@Autowire和@Resource的区别

来源不同:@Resource是Java EE规范定义的注解,而@Autowired是Spring框架定义的注解

注入方式不同@Resource默认按照Bean的名称进行注入,如果找不到与名称相匹配的Bean,则按照类型进行注入。而@Autowired默认按照类型进行注入,如果出现多个相同类型的Bean,则再按照名称进行匹配

属性名称不同:@Autowired没有name属性,而@Resource有name属性,可以指定要注入Bean的名称。

是否支持JSR-330:@Autowired支持JSR-330的@Inject注解,而@Resource不支持。

非自定义Bean注解开发

jar包中的类,并不是我们自己写的,需要使用@Bean注解将其注入容器,还有一点必须要注意,@Bean所在类必须被spring管理,也就是必须加入容器,用@Component也行,@Configuration也行,一般@Configuration

@Component
public class DataSourceTest {
    //将方法返回值Bean实例以@Bean注解指定的名称存储到Spring容器中
    @Bean("datasource")
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
}

配置类注解开发

等非 标签怎样去使用注解替代呢?









 @Configuration注解

@Configuration注解标识的类为配置类,替代原有xml配置文件,该注解第一个作用是标识该类是一个配置类,第二个作用是具备@Component作用

//标注当前类是一个配置类(替代配置文件的)
//底层也封装了@Component注解
@Configuration
public class SpringConfig {
}

@ComponentScan 组件扫描配置 

@Configuration
@ComponentScan({"com.test.service","com.test.dao"})
public class SpringConfig {}

@PropertySource

注解用于加载外部properties资源配置,替代原有xml中的 配置

@Configuration
@ComponentScan
@PropertySource({"classpath:jdbc.properties","classpath:xxx.properties"})
public class SpringConfig {}

  @Import注解

相当于配置

@Configuration
@ComponentScan("com.test.service")
@Import(DataSourceTest.class)
public class SpringConfig {
}

public class DataSourceTest {
    //将方法返回值Bean实例以@Bean注解指定的名称存储到Spring容器中
    @Bean("dataSource")
    public DataSource dataSource(@Value("${jdbc.driver}") String driverClassName, UserDaoImpl userDao){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }


    @Bean
    public DataSource beanTest01(@Qualifier("userDaoImpl") UserDao userDao, UserService userService){
        System.out.println(userDao);
        System.out.println(userService);
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
}

Spring配置其他注解

 @Primary

@Primary注解用于标注相同类型的Bean优先被使用权,与@Component和@Bean一起使用,标注该Bean的优先级更高,则在通过类型获取Bean或通过@Autowired根据类型进行注入时,会选用优先级更高的

@Profile 

注解 @Profile 标注在类或方法上,标注当前产生的Bean从属于哪个环境,只有激活了当前环境,被标注的Bean才能被注册到Spring容器里

不指定环境的Bean,任何环境下都能注册到Spring容器里

使用方式 

命令行参数激活

 -Dspring.profiles.active=test

代码激活 

System.setProperty("spring.profiles.active","test");

Spring注解的解析原理

​@Component在类上标注完,Spring扫描到后,会被实例化成对象,再存储到Spring容器之中,现在研究一下为什么能创建对象

只要将Bean对应的BeanDefinition注册到BeanDefinition,就会经历Bean的生命周期,最终实例化一个Bean,其实就是BeanFactoryProcessor后处理器

不管是xml方式组件扫描还是注解方式组件扫描,最终的扫描方式是一样的,都是使用ClassPathBeanDefinitionScanner扫描器的doScan方法 ,感兴趣可以翻翻源码

你可能感兴趣的:(spring家族,spring,java,前端)