Spring IoC注解详解

这篇文章记录Spring IoC通过注解注入属性的方法。

一、注解注入属性一个简单的案例

1)Spring配置文件引入context约束

<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">

</beans>

2)Spring配置文件中开启注解扫描

<context:component-scan base-package="com.pc.service"/>

注意,在第一步必须要引入context约束,否则无法出现context标签。

3)在类上添加@Component注解

@Component("user")
public class User {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

4)编写测试

ApplicationContext act = new ClassPathXmlApplicationContext("beans-ioc.xml");
User user = (User) act.getBean("user");
System.out.println(user);


二、Spring IoC常用注解详解

1)Bean标注注解

  • @Component :组件通用注解,常用于Model类
  • @Controller :常用于对Controller实现类进行标注
  • @Service:常用于对Service实现类进行标注
  • @Repository:常用于对DAO实现类进行标注

@Component是Spring提供的通用的组件注解。@Component、@Controller、@Service和@Repository功能一样,可以互换,我们使用不同注解主要为了区分被注解的类处在不同的业务层,使逻辑更加清晰。这四个注解主要是定义bean,创建bean。

它们使用方法:

(1)标注在类上

(2)@Component("name")等于@Component(value="user")

(3)@Component相当于@Component("className")

2)Bean属性注入注解

  • @Value :注入普通类型属性
  • @Resource :注入对象类型
  • @Autowired :注入对象类型,默认按照类型注入。结合@Qualifier注解完成按名称的注入。
(1)@Value注解

例如,为上面案例中User类中id和name一个初始值,我们可以在id和name属性上面使用@Value注解,也可以在它们的set方法上使用@Value注解

@Component(value="user")
public class User {
	@Value("1")
	private Integer id;
	
	@Value("lzgsea")
	private String name;
	public Integer getId() {
		return id;
	}
	
	//@Value("1")
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	
	//@Value("lzgsea")
	public void setName(String name) {
		this.name = name;
	}
}
(2)@Resource :注入对象类型
public class UserTest {
	
	@Resource(name = "user")
	private User user;
	
}
(3)@Autowired注解
public class UserTest {
	
	// 按名注入,需要组件设置名称
    // @Resource(name = "user")
    // 和上面功能一样,按名注入
    @Qualifier("user")
    @Autowired
	private User user;
	
}

3)Bean的作用范围注解@Scope

Bean的范围的注解:默认是单例的。

@Scope :在类上添加的,控制类生成的时候采用单例还是多例。 

@Scope取值:

  • singleton :单例
  • prototype :多例
  • request :request域,需要在web环境
  • session :session域,需要在web环境
  • application: context域,需要在web环境
  • globalsession 集群环境的session域,需要在web环境

4)Bean的生命周期注解

@PostConstruct :相当于init-method

@PreDestroy :相当于destroy-method

这两注解用在方法上面。

    @PostConstruct
    public void init() {
    	System.out.println("初始化方法......");
    }
    
    @PreDestroy
    public void destroy() {
    	System.out.println("销毁方法......");
    }


三、context:componet-scan

配置<context:annotation-config>后,会扫描@Required、@Autowired、@PostConstruct、@PreDestroy、@Resource等注解。

配置<context:component-scan base-package="xx">标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,除了扫描<context:annotation-config>中所有的注解,还会扫描@Component、@Repository、@Service、@Controller、 @RestController、@ControllerAdvice、@Configuration 这些注解。

<context:component-scan>提供了两个子标签

  • <context:include-filter>
  • <context:exclude-filter>

在说明这两个子标签前,先说一下<context:component-scan>有一个use-default-filters属性,该属性默认为true,这就意味着会扫描指定包下的全部的标有Spring注解的类,并注册成bean。也就是@Component,@Controller,@Service,@Reposity等。所以如果仅仅是在配置文件中这么写

<context:component-scan base-package="lzgsea.*"/>

 use-default-filter此时为true那么会对base-package包或者子包下的所有的进行java类进行扫描,并把匹配的java类注册成bean。

 可以发现这种扫描的粒度有点太大,如果你只想扫描指定包下面的Controller,该怎么办?此时子标签<context:incluce-filter>就起到了勇武之地。如下所示

<context:component-scan base-package="lzgsea.*" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

这样就会只扫描base-package包或者子包下所有@Controller下的java类,并注册成bean。

use-dafault-filter在上面并没有指定,默认就为true,或者直接use-dafault-filter改为true,那么会对base-package包或者子包下的所有的进行java类进行扫描。

<context:component-scan base-package="lzgsea.*">  
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
</context:component-scan>  

此时,spring不仅扫描了@Controller,还扫描了指定包所在的子包service包下注解@Service的java类。此时指定的include-filter不任何起到作用。

另外在我参与的项目中可以发现在base-package指定的包中有的子包是不含有注解了,所以不用扫描,此时可以指定<context:exclude-filter>来进行过滤,说明此包不需要被扫描。

综合以上说明:

use-default-filters="false"的情况下不会自动扫描,需要配置<context:include-filter>指定扫描哪些注解

use-dafault-filters="false"的情况下:<context:include-filter>指定的扫描。

use-default-filters="true"的情况下:<context:exclude-filter>指定的不扫描

  • 13
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值