Spring用注解方式实现IOC和DI

1. 什么是注解
所谓注解就是给程序看的提示信息,很多时候都用来作为轻量级配置的方式,(java基础加强部分内容)
2. Spring中的注解
Spring除了默认的使用xml配置文件的方式实现配置之外,也支持使用注解方式实现配置,这种方式效率更高,配置信息清晰,修改方便,推荐使用.
引入context名称空间:
在编辑软件中导入spring-context-3.2.xsd约束文件,要求Spring管理,
在applicationContext.xml文件中,引入该schema文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        ">
</beans>

可以添加至模板,方便后续使用
3. 使用类注解
使用Spring的类注解可以通过注解注册类为bean,省去了配置文件中的配置.
a. 开启包扫描
在spring的配置文件中,开启包扫描,指定spring自动扫描哪些包下的类.

<context:component-scan base-package="cn.tedu.beans"/>

案例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
">
<!-- 开启包扫描 -->
	<context:component-scan base-package="cn.tedu.beans"></context:component-scan>
	<!-- 
	<bean id="person" class="cn.tedu.beans.Person"></bean>        
	<bean id="cat" class="cn.tedu.beans.Cat"></bean>        
	<bean id="dog" class="cn.tedu.beans.Dog"></bean>        
	 -->
</beans>

b.使用注解注册bean
这个包中的类会在spring容器启动时自动被扫描,检测是否需要自动配置为bean.在配置的包中的类上使用@Component
注解,则这个类会自动被注册为bean,使用当前类的class为的class,通常情况下使用类名首字母小写为id。
案例:

package cn.tedu.beans;
import org.springframework.stereotype.Component;
 
	@Component
	public class Person{
}

c. bean的id
可以使bean类实现BeanNameAware接口,并实现其中的setBeanName方法,spring容器会在初始化bean时,调用此方法告知当前bean的id。通过这个方式可以获取bean的id信息。
通常情况下注解注册bean使用类名首字母小写为bean的id,但是如果类名的第二个字母为大写则首字母保留原样.
案例:

cn.tedu.beans.Person --> <bean id="person" class="cn.tedu.beans.Person"/>
cn.tedu.beans.NBA --> <bean id="NBA" class="cn.tedu.beans.NBA"/>

也可以通过在@Component中配置value属性,明确的指定当前类在注册到spring时bean的id
案例:

package cn.tedu.beans;
 
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
 
	@Component("per")
	public class Person implements BeanNameAware{
	@Override
	public void setBeanName(String name) {
		System.out.println("==="+this.getClass().getName()+"==="+name);
	}
}

4.使用属性注解
使用属性注解,可以为bean配置属性的注入过程,省去了在配置文件中进行注入配置的过程,更加便捷。
a. 在配置文件中开启属性注解功能

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
">
	<!-- 开启属性注解 -->
	<context:annotation-config></context:annotation-config>
</beans>

b. 使用属性注解注入bean类型数据:
在bean中的属性上通过如下注解声明属性注入
@Autowired
也可以使用
@Qualifier(value=“dog1”)
注解,明确的指定,要注入哪个id的bean
案例:

package cn.tedu.beans;
 
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
 
public class Person implements BeanNameAware{
	@Autowired
	private Dog dog;
	@Autowired
	private Cat cat;
 
	public Dog getDog() {
		return dog;
	}
	public void setDogx(Dog dog) {
		this.dog = dog;
	}
	public Cat getCat() {
		return cat;
	}
	public void setCat(Cat cat) {
		this.cat = cat;
	}
	@Override
	public String toString() {
		return "Person [dog=" + dog + ", cat=" + cat + "]";
	}
 
	@Override
	public void setBeanName(String name) {
		System.out.println("=============="+this.getClass().getName()+"===="+name);
	} 
}

c. 属性注入bean类型数据的原理:
当spring容器解析xml时,发现开启了属性注解,则会在创建bean时,检测属性上是否存在@Autowired注解,如果发现该注解,则会通过当前属性的名称寻找是否存在该id的bean,如果存在则注入进来,如果不存在,再检查是否存在和当前属性类型相同的bean,如果有则注入进来,如果都没有则抛出异常.

**也可以使用@Resource(name=“id”)指定注入给定id的bean,但是这种方式不建议大家使用。
d.spring内置支持注入类型的注解方式的注入 - 非集合类型
spring中可以通过注解方式 注册bean,并可以通过@Autowired实现属性的自动注入,但注入的都是自定义的bean类型,如果类中包含例如 int long String等spring内置可注入的类型时,又该如何注入呢? 可以使用@Value注解来实现注入。

package cn.tedu.beans;
 
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
	@Component("per")
	public class Person implements BeanNameAware{
	@Value("999")
	private int id;
 
	@Value("zs")
	private String name;
 
	@Autowired
	private Dog dog;
 
	@Autowired
	private Cat cat;
 
	public Dog getDog() {
		return dog;
	}
	public void setDogx(Dog dog) {
		this.dog = dog;
	}
	public Cat getCat() {
		return cat;
	}
	public void setCat(Cat cat) {
		this.cat = cat;
	}
 
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", dog=" + dog + ", cat=" + cat + "]";
	}
	@Override
	public void setBeanName(String name) {
		System.out.println("==="+this.getClass().getName()+"==="+name);
	}
 
}

这种方式可以实现spring内置类型的注入,但是这种方式将注入的值写死在了代码中,后续如果希望改变注入的初始值,必须来修改源代码,此时可以将这些值配置到一个properties配置文件中,再在spring中进行引入。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
e. spring内置支持注入类型的注解方式的注入 - 集合类型
需要将集合类型的数据配置到spring配置文件中,再通过@Value引入
配置过程:
将spring-util-3.2.xsd交给MyEclipse管理在当前spring容器的配置文件中导入util名称空间再通过适当的util标签注册数据
案例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd
">
	<!-- 开启属性注解 -->
	<context:annotation-config></context:annotation-config>
	<context:component-scan base-package="cn.tedu.beans"></context:component-scan>
	<context:property-placeholder location="classpath:/person-data.properties"/>
 
	<util:list id="l1">
		<value>北京</value>
		<value>上海</value>
		<value>广州</value>
		<value>深圳</value>
	</util:list>
 
	<util:set id="s1">
		<value>法师</value>
		<value>射手</value>
		<value>打野</value>
		<value>战士</value>
		<value>打野</value>
		<value>坦克</value>
		<value>打野</value>
	</util:set>
 
	<util:map id="m1">
		<entry key="k1" value="v1"></entry>
		<entry key="k2" value="v2"></entry>
		<entry key="k3" value="v3"></entry>
		<entry key="k1" value="v4"></entry>
	</util:map>        
</beans>

再在类的属性中通过@Value注入赋值

package cn.tedu.beans;
 
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
	@Component("per")
	public class Person implements BeanNameAware{
	@Value("${id}")
	private int id;
 
	@Value("${name}")
	private String name;
 
	@Value("#{@l1}")
	private List<String> addr;
 
	@Value("#{@s1}")
	private Set<String> jobs;
 
	@Value("#{@m1}")
	private Map<String,String> map;
 
	@Autowired
	private Dog dog;
 
	@Autowired
	private Cat cat;
 
	public Dog getDog() {
		return dog;
	}
	public void setDogx(Dog dog) {
		this.dog = dog;
	}
	public Cat getCat() {
		return cat;
	}
	public void setCat(Cat cat) {
		this.cat = cat;
	}
 
	public void setBeanName(String name) {
		System.out.println("=============="+this.getClass().getName()+"===="+name);
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", addr=" + addr + ", jobs=" + jobs + ", map=" + map + ", dog=" + dog + 				", cat=" + cat + "]";
	}
}

5. 其他注解
a. @Scope(value=“prototype”)
配置修饰的类的bean是单例还是多例,如果不配置默认为单例
案例:

package cn.tedu.beans;
 
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
 
	@Component
	@Scope("prototype")
	public class Dog {
 	}

b.@Lazy
配置修饰的类的bean采用懒加载机制
案例:

package cn.tedu.beans;
 
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
 
	@Component
	@Lazy
	public class Dog {
	public Dog() {
		System.out.println("Dog...被创建出来了...");
	}
}

c. @PostConstruct
在bean对应的类中 修饰某个方法 将该方法声明为初始化方法,对象创建之后立即执行。
d. @PreDestroy
在bean对应的类中 修饰某个方法 将该方法声明为销毁的方法,对象销毁之前调用的方法。
案例:

package cn.tedu.beans;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
import org.springframework.stereotype.Component;
 
	@Component
	public class Dog {
	public Dog() {
		System.out.println("Dog...被创建出来了...");
	}
 
	@PostConstruct
	public void init(){
		System.out.println("Dog的初始化方法。。。");
	}
 
	@PreDestroy
	public void destory(){
		System.out.println("Dog的销毁方法。。。");
	}
}

e. @Controller @Service @Repository @Component
这四个注解的功能是完全相同的,都是用来修饰类,将类声明为Spring管理的bean的。
其中@Component一般认为是通用的注解
@Controller用在软件分层中的控制层,一般用在web层
@Service用在软件分层中的业务访问层,一般用在service层
@Repository用在软件分层中的数据访问层,一般用在dao层

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值