Spring知识点总结(三)之注解方式实现IOC和DI
1. 注解概念
所谓注解就是给程序看的提示信息,很多时候都用来作为轻量级配置的方式。
关于注解的知识点,参看java基础课程中java基础加强部分的内容。
2. Spring中的注解
Spring除了默认的使用xml配置文件的方式实现配置之外,也支持使用注解方式实现配置,这种方式效率更高,配置信息清晰,修改更方便,推荐使用。
引入context名称空间:
在MyEclipse中导入spring-context-3.2.xsd约束文件,要求Spring来管理。
在applicationContext.xml文件中,引入该schema文件:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context-3.2.xsd
9 ">
10 </beans>
**可以将以上头信息加入MyEclipse模版,方便后续自动生成。
3. 使用类注解
使用Spring的类注解可以通过注解注册类为bean,省去了配置文件中的<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为<bean>的class,通常情况下使用类名首字母小写为<bean>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层
Spring知识点总结(三)之注解方式实现IOC和DI的更多相关文章
- Spring 注解方式 实现 IOC 和 DI
注:以下所有测试案例(最后一个除外)的测试代码都是同一个: package cn.tedu.test; import org.junit.Test; import org.springframewor ...
- (转)Spring的bean管理(注解方式)
http://blog.csdn.net/yerenyuan_pku/article/details/69663779 Spring的bean管理(注解方式) 注解:代码中的特殊标记,注解可以使用在类 ...
- spring Bean的三种配置方式
Spring Bean有三种配置方式: 传统的XML配置方式 基于注解的配置 基于类的Java Config 添加spring的maven repository <dependency> ...
- Spring 的 Bean 管理(注解方式)
Spring 的 Bean 管理(注解方式) 1. 导入必要的 jar 包和 xml 文件 使用注解需要导入 spring-aop 的 jar 包. applicationContext.xml 文件 ...
- 【Spring】XML方式实现(无参构造 有参构造)和注解方式实现 IoC
文章目录 Spring IoC的实现方式 XML方式实现 通过无参构造方法来创建 1.编写一个User实体类 2.编写我们的spring文件 3.测试类 UserTest.java 4.测试结果 通过 ...
- Spring 使用纯注解方式完成IoC
目录 创建一个简单的Person类 使用xml方式配置Spring容器并获取bean的过程 创建xml配置文件 进行测试 使用纯注解方式配置Spring容器并获取bean的过程 创建spring配置类 ...
- 你可能使用了Spring最不推荐的注解方式
前言 使用Spring框架最核心的两个功能就是IOC和AOP.IOC也就是控制反转,我们将类的实例化.依赖关系等都交由Spring来处理,以达到解耦合.利用复用.利于测试.设计出更优良程序的目的.而对 ...
- Spring常用的三种注入方式
好文要收藏,摘自:https://blog.csdn.net/a909301740/article/details/78379720 Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入 ...
- Spring的bean管理(注解方式)
注解:代码中的特殊标记,注解可以使用在类.方法.属性上面,使用注解可实现一些基本的功能.注解的写法是@注解名称(属性=属性值). 使用注解创建对象 第一步,创建Web项目,引入Spring的开发包 第 ...
随机推荐
- 深入理解理解 JavaScript 的 async/await
原文地址:https://segmentfault.com/a/1190000007535316,首先感谢原文作者对该知识的总结与分享.本文是在自己理解的基础上略作修改所写,主要为了加深对该知识点的理 ...
- 深入理解JavaScript系列(27):设计模式之建造者模式
介绍 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定. ...
- SQLite 大小写敏感
--转自mojianpo http://mojianpo.iteye.com/blog/1496579 大部分数据库在进行字符串比较的时候,对大小写是不敏感的. 但是,在SQLite中,对大小写是敏 ...
- SQL脚本整理系列 三
触发器 SQL 2008 怎么实现删除学生表里面的一条记录,成绩表里面关于这个学生的记录也同时删掉,谢求具体代码 --创建表 DROP TABLE tstudent GO CREATE TABLE t ...
- double类型计算
下面两个例子体现两个运算规则 一.四舍五入 //四舍五入 double doublenum = Math.Round(12.5, MidpointRounding.AwayFromZero); //两 ...
- python中的字符串 列表 字典
字符串 一个有序的字符集合 不可变 1,可以使用for in语句进行迭代循环,返回元素 2,in类是于str.find()方法但是是返回布尔结果 str.find()返回 ...
- Python contextlib.contextmanager
看着代码又发现了一个奇怪的东西: @contextlib.contextmanager def __call__(self, incoming): result_wrapper = [] yield ...
- drupal对数据库操作
// nodenode_load($nid = NULL, $vid = NULL, $reset = FALSE);node_load_multiple($nids = array(), $cond ...
- HBase伪分布式安装(HDFS)+ZooKeeper安装+HBase数据操作+HBase架构体系
HBase1.2.2伪分布式安装(HDFS)+ZooKeeper-3.4.8安装配置+HBase表和数据操作+HBase的架构体系+单例安装,记录了在Ubuntu下对HBase1.2.2的实践操作,H ...
- 随学笔记 partAdded
随学笔记: RectangularDropShadow为矩形对象添加阴影,DropShadowFilter可以为任意形状对象添加阴影. BorderContainer和Panel等容器使用的就是Rec ...