Spring IOC常用注解

SpringIOC常用注解

IOC常用注解

1. 用于注解驱动的注解

1.1 @Configuration

1.1.1 作用
spring3.0版本后加入,是spring支持注解开发的一个标志
表明当前类为spring的一个配置类,用来替代applicationContext.xml
本质为一个@Component注解,被此注解修饰的类,也会被存入spring的Ioc容器
1.1.2 使用场景
用于注解驱动开发时用于编写配置的类,@Configuration通常用于主配置类上
注意: 注解驱动开发时,如果构建Ioc容器用的是传入字节码的构造函数,此注解可以省略,但如果使用传入包的构造函数,则不能省略
1.1.3 属性分析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

/*Explicitly specify the name of the Spring bean definition associated with the @Configuration class. If left unspecified (the common case), a bean name will be automatically generated.
The custom name applies only if the @Configuration class is picked up via component scanning or supplied directly to an AnnotationConfigApplicationContext. If the @Configuration class is registered as a traditional XML bean definition, the name/id of the bean element will take precedence.
Returns:
the explicit component name, if any (or empty String otherwise)
See Also:
AnnotationBeanNameGenerator*/
	@AliasFor(annotation = Component.class)
	String value() default ""; // 用于存入spring的Ioc容器中Bean的id
}
1.1.4 示例
在入门中,由于没有applicationContext.xml,不能在xml中配置spring常见容器中要扫描的包,使自己编写的类无法加入到Ioc容器,此时可以用注解来代替配置文件
/**
 * spring注解驱动开发的配置类
 * 相当于applicationContext.xml
 * @author 刘淳
 */
@Configuration
public class SpringConfiguration {
}
1.1.5 测试
/**
 * 测试@Configuration注解
 * @author 刘淳
 */
public class SpringConfigurationTest {
    /**
     * 测试方法
     */
    public static void main(String[] args) {
        //扫描包方式创建容器  需在配置类上使用@Configuration注解
        //1.创建容器
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext("config");
        //2.获取对象
        SpringConfiguration configuration = applicationContext.getBean(SpringConfiguration.class);
        //3.输出结果
        System.out.println(configuration);
        //config.SpringConfiguration$$EnhancerBySpringCGLIB$$79a0bbb9@70b0b186
        
        //传入配置类字节码方式创建容器  @Configuration可省略
        //1.创建容器
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);
        //2.获取对象
        SpringConfiguration configuration = applicationContext.getBean(SpringConfiguration.class);
        //3.输出结果
        System.out.println(configuration); 
        //config.SpringConfiguration@6325a3ee
    }
}

1.2 @ComponentScan

1.2.1 作用
用于指定创建容器时要扫描的包,扫描位置可以指定扫描的包名,也可指定扫描的类的字节码(扫描该类所在包及其子包)。
支持定义扫描规则,例如包含或排除某些部分
支持自定义Bean的命名规则
1.2.2 使用场景
注解驱动开发时,要想spring将自己编写的类添加到Ioc容器中,就需要使用该注解实现组件扫描
PS:spring4.3版本后加入@ComponentScans注解,支持配置多个@ComponentScan
1.2.3 属性分析
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

	/**
	 *用于指定要扫描的包,spring会扫描指定的包及其子包下的所有类
	 */
	@AliasFor("basePackages")
	String[] value() default {};

	/**
	 *与value互为别名引用
	 */
	@AliasFor("value")
	String[] basePackages() default {};

	/**
	 *指定具体要扫描的类的字节码 会扫描该类所在的包及其子包
	 */
	Class<?>[] basePackageClasses() default {};

	/**
	 *指定扫描Bean对象存入容器时的命名规则,可以自定义命名规则(实现BeanNameGenerator接口)
	 */
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	/**
	 *处理并转换检测到的Bean的作用范围
	 */
	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

	/**
	 *指定Bean生成时的代理方式
	 *默认为Default(等同于No),不使用代理
	 */
	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

	/**
	 *用于指定符合组件检测条件的类文件,默认为包扫描下的 **/*.class
	 */
	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;

	/**
	 *是否对带有@Component @Repository @Service @Controller注解的类开启检测,默认是开启的
	 */
	boolean useDefaultFilters() default true;

	/**
	 *自定义组件扫描的过滤规则,用以扫描组件
	 */
	Filter[] includeFilters() default {};

	/**
	 *自定义组件的排除规则
	 */
	Filter[] excludeFilters() default {};

	/**
	 *组件扫描时是否采用懒加载,默认不开启
	 */
	boolean lazyInit() default false;


	/**
	 *过滤规则
	 */
	@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {

		/**
		 *FilterType有5种类型:
          ANNOTATION, 注解类型 默认
          ASSIGNABLE_TYPE,指定固定类
          ASPECTJ, ASPECTJ类型
          REGEX,正则表达式
          CUSTOM,自定义类型
		 */
		FilterType type() default FilterType.ANNOTATION;

		/**
		 *要过滤的类类的字节码文件
		 */
		@AliasFor("classes")
		Class<?>[] value() default {};

		/**
		 *等同于classes
		 */
		@AliasFor("value")
		Class<?>[] classes() default {};

		String[] pattern() default {};

	}

}
1.2.4 示例
要将使用了@Component及其衍生注解配置的Bean加入Ioc容器,就得使用@ComponentScan
注解驱动开发JaveEE项目时,Ioc容器分为 RootApplicationContextServletApplicationContext
我们不希望Controller加入到Root容器中,可以使用过滤规则排除@Controller注解配置的Bean
/**
* spring的配置类
* @author 刘淳
*/
@Configuration
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbc.properties")
@ComponentScan(value="com.liuchun",excludeFilters=@ComponentScan.Filter(type = FilterType.ANNOTATION,classes =Controller.class))
public class SpringConfiguration {
}

1.3 @Bean

1.3.1 作用
写在方法上,将当前方法的返回值存入spring的Ioc容器
写在注解上,作为元注解使用
1.3.2 使用场景
在基于注解的配置中,如果要存入容器的Bean不是我们写的类,此时无法在类上添加@Component注解,需要使用@Bean加入容器
1.3.3 属性分析
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
    /**
     *指定存入spring容器中Bean的标识
     *支持指定多个标识,默认值为当前方法名称
     */
    @AliasFor("name")
    String[] value() default {};
    /**
     *spring4.3.3版本后加入,和name属性一样
     */
    @AliasFor("value")
    String[] name() default {};
    /**
     *spring5.1开始已弃用
     */
    @Deprecated
    Autowire autowire() default Autowire.NO;
    /**
     *用于指定是否支持自动按类型注入到其它Bean中,只影响@Autowired注解的使用
     *默认值为True 允许使用自动按类型注入
     */
    boolean autowireCandidate() default true;
    /**
     *用于指定初始化方法
     */
    String initMethod() default "";
    /**
     *用于指定销毁方法
     */
    String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}

1.3.4 示例
//将JdbcTemplate加入到容器中
@Bean("jdbcTemplate")
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}

1.4 @Import

1.4.1 作用
写在类上,与注解驱动配置类一起使用,引入其他配置类
使用此注解后,可以和早期xml配置一样,分别配置不同内容,使配置更加清晰
指定此注解后,被引入的类上不可以再使用@Configuration,@Compnent等注解
1.4.2 使用场景
注解驱动开发时,由于配置项过多,如果都写在一个类里,配置结构和内容将杂乱不堪,使用此注解可以把配置项进行分门别类进行配置
1.4.3 属性分析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    /**
     *用于指定其它配置类的字节码,至此指定多个配置类
     */
    Class<?>[] value();
}
1.4.4 示例
/**
 * spring配置类
 * @author 刘淳
 */
@Configuration
@Import(JdbcConfig.class)  // 引入Jdbc的配置类
@ComponentScan("com.liuchun")
public class SpringConfiguration {
}

1.5 @ProperySource

1.5.1 作用
指定读取资源文件的位置
支持properties以及xml文件
通过YAML解析器,配合自定义PropertySourceFactory可实现解析yml配置文件
1.5.2 使用场景
使用注解驱动后,xml配置文件就没有了,此时如果一些配置直接写在类中,会造成和java源码的紧密耦合,修改有极大困难,而用properties或yml来配置就会变得很灵活,此时就需要此注解来将其引入
1.5.3 属性分析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {

	/**
	 *指定资源的名称,未指定则根据基础资源描述生成
	 */
	String name() default "";

	/**
	 *指定资源位置,可以为类路径或文件路径
	 */
	String[] value();

	/**
	 *是否忽略资源文件不存在,默认为false,当资源文件不存在spring启动将报错
	 */
	boolean ignoreResourceNotFound() default false;

	/**
	 *指定解析文件使用的字符集,有中文时需指定中文的字符集
	 */
	String encoding() default "";

	/**
	 *指定读取对应资源文件的工厂类,默认为PropertySourceFactory
	 */
	Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;

}
1.5.4 示例
连接数据库的信息如果直接写在JdbcConfig中,需要修改时就面临修改源码的问题
可选择使用@PropertySource和SpringEL表达式,就可将配置存入properties文件
1.5.4.1 Jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=lc20000925
1.5.4.2 JdbcConfig
/**
* 连接数据库的配置
* @author 刘淳
*/
public class JdbcConfig {
    
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
}
1.5.4.3 SpringConfiguration
/**
 * spring配置类
 * @author 刘淳
 */
@Configuration
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbc.properties")
@ComponentScan("com.liuchun")
public class SpringConfiguration {
}

2. 注入时机和设定注入条件的注解

2.1 @DependsOn

2.1.1 作用
用于指定某个类的创建依赖的Bean对象先创建
使用此注解可指定Bean的加载顺序(在基于注解配置中,是按照类中方法的书写顺序决定的)
2.1.2 使用场景
在观察者模式中,分为事件,事件源和监听器。
一般情况下,我们的监听器负责监听事件源,当事件源触发事件时,监听器捕获并作出处理
因此监听器的创建应在事件源之前,此时可以用@DependsOn实现
2.1.3 属性分析
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
    /**
     *指定Bean的唯一标识,被指定的Bean会在当前Bean创建前加载
     */
	String[] value() default {};
}

2.1.4 示例
/**
* @author 刘淳
*/
@Component
public class CustomerListener {
    
    public CustomerListener(){
        System.out.println("监听器创建了。。。");
    }
}
/**
* @author 刘淳
*/
@Component
@DependsOn("customerListener")
public class Customer {
    
    public Customer(){
        System.out.println("事件源创建了。。。");
    }
}

2.2 @Lazy

2.2.1 作用
指定单例Bean对象的创建时机
不使用此注解时,单例对象的生命周期与容器相同
使用此注解后,单例对象的创建时机变成了第一次使用时创建
2.2.2 使用场景
实际开发中当Bean为单例对象时,并不是每个都需要一开始就加载到Ioc容器中,有些可以在使用时再加载,此注解即可完成该需求(此注解只对单例Bean对象起作用,指定@Scope的prototype后失效)
2.2.3 属性分析
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR,
ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
    /**
     *指定是否采用延迟加载 默认开启
     */
	boolean value() default true;
}

2.3 @Conditional

2.3.1 作用
根据条件选择注入的Bean对象
2.3.2 使用场景
开发时往往使用多平台来测试,例如测试数据库分别部署于Linux和Windows上,使用此注解可以根据工程环境选择连接的数据库
2.3.3 属性分析
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    /**
     *用于提供一个Condition接口的实现类,实现类中编写具体代码实现注入的条件
     */
    Class<? extends Condition>[] value();
}

3. 用于创建对象的注解

@Component,@Contorller,@Service,@Repository

1. 作用
这四个注解都用于修饰类,把当前类创建一个对象并存入Spring的Ioc容器中
实例化时首选默认无参构造函数,同时支持带参构造,但参数依赖必须有值,否则抛出异常
2. 使用场景
当需要把自己编写的类加入到Ioc容器中时,可以使用以上四个注解实现
@Component注解通常用于非三层对象中
@Contorller,@Service,@Repository 三注解一般针对三层对象使用,提供更加精准的语义化配置
spring注解驱动开发时,如果类没有加入到Ioc容器,那么里面的属性和方法上的注解都不会被解析
3. 属性分析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
    /**
     *用于指定存入容器时Bean的id 默认值为当前类的名称
     */
    String value() default "";
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
    
    @AliasFor(annotation = Component.class)
    String value() default "";
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    
    @AliasFor(annotation = Component.class)
    String value() default "";
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    
    @AliasFor(annotation = Component.class)
    String value() default "";
}
4. 示例
正确的方式1:使用默认构造函数
    /**
     * 用于记录系统日志
     * @author 刘淳 
     */
    @Component
    public class LogUtil {
        /**
         * 默认无参构造函数
         */
        public LogUtil(){
        }
    }
正确的方式2:在构造函数中注入一个已经在容器中的bean对象。
    /**
    * 此处只是举例:使用JdbcTemplate作为持久层中的操作数据库对象
    * @author 刘淳
    */
    @Repository("userDao")
    public class UserDaoImpl implements UserDao{
        private JdbcTemplate jdbcTemplate ;
        /**
         * 此时要求容器中必须有JdbcTemplate对象
         * @param jdbcTemplate
         */
        public UserDaoImpl(JdbcTemplate jdbcTemplate){
            this.jdbcTemplate = jdbcTemplate;
        }
    }
正确的方式3:在构造函数中注入一个读取配置文件获取到的值。
    /**
    * 用于记录系统日志
    * @author 刘淳
    */
    @Component
    public class LogUtil {
        /**
         * 构造时,注入日志级别
         * @param logLevel
         */
        public LogUtil(@Value("${log.level}")String logLevel){
        	System.out.println(logLevel);
        }
    }
错误的方式:由于logLevel没有值,所以运行会报错。
    /**
    * 用于记录系统日志
    * @author 刘淳
    */
    @Component
    public class LogUtil {
        /**
         * 构造时,注入日志级别
         * @param logLevel
         */
        public LogUtil(String logLevel){
        	System.out.println(logLevel);
        }
    }

4. 用于注入数据的注解

4.1 @Autowired

4.1.1 作用
自动按照类型注入
当Ioc容器中有且只有一个类型匹配时可以直接注入成功
当超过一个匹配时,则使用变量名称(若写在方法上则为方法名称)作为Bean的id,在符合类型的Bean中再次匹配,匹配上则注入成功。
匹配不上时,根据required属性的取值决定是否报错
4.1.2 使用场景
自己写的类中注入依赖Bean对象时,可以采用此注解
4.1.3 属性分析
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    /**
     * 是否必须注入成功 默认值为true
     * 取值为true时,注入不成功将会报错
     */
    boolean required() default true;
}

4.1.4 示例
/**
* 使用Jdbc作为持久层中的操作数据库对象
* @author 刘淳
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao{
    @Autowired
    private JdbcTemplate jdbcTemplate ;
}

4.2 @Qualifier

4.2.1 作用
当使用自动按类型注入时,有多个类型匹配的时候,就可以使用此注解明确注入哪个Bean对象
通常情况下必须配置@Autowired注解一起使用
2.2 使用场景
当容器中有两个类型相同的Bean对象的时候,就可以使用此注解注入
如果把要注入的变量名称改为和要注入Bean的id一致则可以不使用此注解
4.2.3 属性分析
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
    /**
     * 指定Bean的唯一标识
     */
	String value() default "";
}

4.3 @Resource

4.3.1 作用
此注解来源于JSR规范(Java Specification Requests),用于找到依赖的组件注入到应用
利用了JNDI(Java Naming and Directory Interface Java 命名目录接口 J2EE规范之一)技术查找所需的资源
1. 所有属性都不指定,默认按照byType的方式装配Bean对象
2. 指定name,不指定type,则采用byName装配Bean对象
3. 不指定name,指定type,按照byType装配Bean对象
4. name,type都指定,两个都校验,有任何一个不符合条件就报错
4.3.2 使用场景
当我们某个类的依赖Bean在Ioc容器中存在多个的时候,可以使用此注解指定特定的Bean对象注入
等同于@Autowired配合@Qualifier注入
4.3.3 属性分析
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
    /**
     *资源的JNDI名称 在spring注入时指定Bean的唯一标识
     */
    String name() default "";
    /**
     *引用指向的资源名称 它可以使用全局JNDI名称链接到任何兼容的资源
     */
    String lookup() default "";
    /**
     *指定Bean的类型
     */
    Class<?> type() default java.lang.Object.class;
    /**
     *指定资源的身份验证类型,它只能为任何受支持类型的连接工厂的资源指定此选项,而不能为其它类型的资源指定此选项
     */
    enum AuthenticationType {
    CONTAINER,
    APPLICATION
    }
    AuthenticationType authenticationType() default
    AuthenticationType.CONTAINER;
    /**
     *指定此资源是否可以在此组件和其它组件之间共享
     */
    boolean shareable() default true;
    /**
     *指定资源的映射名称
     */
    String mappedName() default "";
    /**
     *指定资源的描述
     */
    String description() default "";
}

4.4 @Value

4.4.1 作用
用于注入基本类型和String类型的数据
支持spring的EL表达式,可通过${} 的方式获取配置文件(properties,xml,yml)中的数据
4.4.2 使用场景
实际开发中,连接数据库的配置等可以用配置文件保存,此时读取配置文件可以使用EL表达式读取
4.4.3 属性分析
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
    /**
     *指定注入的数据或EL表达式
     */
    String value();
}
4.4.4 示例
4.4.4.1 Jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=lc20000925
4.4.4.2 JdbcConfig
/**
* 连接数据库的配置
* @author 刘淳
*/
public class JdbcConfig {
    
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource")
    public DataSource createWindowsDataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

4.5 @Inject

4.5.1 作用
用于建立依赖关系,与@Resource和@Autowired作用一样
使用前需导入坐标:
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
区别:
  @Autowired:来源于spring框架自身,默认为byType自动装配,当配合了@Qualifier注解后,由@Qualifier实现byName装配。有一个required属性,用于指定是否必须注入成功
  @Resource:来源于JSR-250规范,在没有指定name属性时为byType自动装配,指定name后采用byName方式自动装配
  @Inject:来源于JSR-330规范(Jcp给出的官方标准反向依赖注入规范),不支持任何属性,但可以配合@Qualifier或@Primary注解使用。默认byType装配,指定JSR-330规范中的@Named注解后变为byName装配
4.5.2 使用场景
使用@Autowired注解的地方,都可以替换成@Inject
可以出现在方法,构造函数和字段上
JRE无法决定构造方法注入的优先级,规范中规定类中只能有一个构造方法带@Inject
4.5.3 示例
/**
* 第一种写法: 写在字段上
* 此处只是举例:使用Jdbc作为持久层中的操作数据库对象
* @author 刘淳
*/
@Repository("userDao")
public class UserDaoImpl implements UserDao{
    @Inject
    private JdbcTemplate jdbcTemplate ;
}
/**
* 第二种写法:写在构造函数上
* 此处只是举例:使用Jdbc作为持久层中的操作数据库对象
* @author 刘淳
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao{
    private JdbcTemplate jdbcTemplate ;
    /**
     * 此时要求容器中必须有JdbcTemplate对象
     */
    @Inject
    public AccountDaoImpl(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
    }
}
/**
* 第三种写法:配合@Named注解使用
* 此处只是举例:使用Jdbc作为持久层中的操作数据库对象
* @author 刘淳
*/
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao{
    @Inject
    @Named("jdbcTemplate")
    private JdbcTemplate jdbcTemplate ;
}

4.6 @Primary

4.6.1 作用
指定Bean的注入优先级,被@Primary修饰的Bean对象优先注入
4.6.2 使用场景
依赖对象有多个存在时,使用此注解表示优先使用被@Primary注解的Bean,当不存在时使用其它Bean对象
4.6.3 示例
AccountServiceImpl中的accountDao将会优先注入AccountDaoImpl2,当要注入AccountDaoImpl时,可用@Qualifier("accountDaoImpl1")注入
/**
* @author 刘淳
*/
@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;
    public void save(){
    	System.out.println(accountDao);
    }
}
/**
* 此处只是举例:使用Jdbc作为持久层中的操作数据库对象
* @author 刘淳
*/
@Repository("accountDaoImpl1")
public class AccountDaoImpl implements AccountDao{
    @Override
    public String toString() {
        return "accountDaoImpl1";
    }
}
/**
* 此处只是举例:使用Jdbc作为持久层中的操作数据库对象
* @author 刘淳
*/
@Repository("accountDaoImpl2")
@Primary
public class AccountDaoImpl2 implements AccountDao{
    @Override
    public String toString() {
        return "accountDaoImpl2";
    }
}

5. 生命周期以及作用范围相关的注解

5.1 @Scope

5.1.1 作用
用于指定Bean对象的作用范围
5.1.2 使用场景
Bean对象默认都是单例的,当必须配置为多例时,可用该注解实现
5.1.3 属性分析
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
    /**
     * 指定作用范围的取值 默认值为""
     * spring初始化容器时会借助ConfigurableBeanFactory中的类成员:
     * 	String SCOPE_SINGLETON = "singleton"
     */
    @AliasFor("scopeName")
    String value() default "";
    /**
     * 与value互为别名引用
     */
    @AliasFor("value")
    String scopeName() default "";
    /**
     * 指定Bean对象代理方式,指定的是ScopedProxyMode枚举的值
     *	DEFAULT:默认值。(就是NO)
	 *	NO:不使用代理。
	 *	INTERFACES:使用JDK官方的基于接口的代理。
	 *	TARGET_CLASS:使用CGLIB基于目标类的子类创建代理对象。
     */
    ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}

5.2 @PostConstruct

5.2.1 作用
指定Bean对象的初始化方法
5.2.2 使用场景
Bean对象创建完成后,如需要对成员进行初始化操作,可以使用此注解配置初始化方法
5.2 3 属性分析
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}

5.3 @PreDestroy

5.3.1 作用
指定Bean对象的销毁方法
5.3.2 使用场景
在Bean对象销毁之前,进行一些清理操作
5.3.3 属性分析
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@未安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值