【Spring】Spring中的Bean - 5、Bean的装配方式(XML、注解(Annotation)、自动装配)
Bean的装配方式
简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean
IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
控制反转(IoC)是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
依赖注入
什么是Bean的装配?
Bean的装配方式是将Bean装配注入到Spring IoC容器中 ,Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配)。基于注解的装配方式尤其重要,它是当前的主流装配方式。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
基于XML的装配
Spring提供了两种基于XML的装配方式:设值注入(Setter Injection)和构造注入(Constructor Injection)。下面就讲解下如何在XML配置文件中使用这两种注入方式来实现基于XML的装配。
在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式调用setter方法来注入属性值。因此,设值注入要求一个Bean必须满足以下两点要求。
- Bean类必须提供一个默认的无参构造方法。
- Bean类必须为需要注入的属性提供对应的setter方法。
使用设值注入时,在Spring配置文件中,需要使用元素的子元素来为每个属性注入值;
而使用构造注入时,在配置文件里,需要使用元素的子元素来定义构造方法的参数,可以使用其value属性(或子元素)来设置该参数的值。
下面通过一个案例来演示基于XML方式的Bean的装配。
基于XML的装配,使用方式如下:
创建Java类,提供有参、无参构造以及属性setter方法;
(1)在chapter02模块的src/main/java目录下,创建一个com.awen.assemble包,在该包中创建User类,并在类中定义username、password和list集合三个属性及其对应的setter方法,如文件所示。文件 User.java
```java
package com.awen.assemble;
import java.util.List;
public class User {
private String username;
private Integer password;
private List list;
/**
* 1.使用构造注入
* 1.1提供带所有参数的有参构造方法。
/
public User(String username, Integer password, List list) {
super();
this.username = username;
this.password = password;
this.list = list;
}
/*
* 2.使用设值注入
* 2.1提供默认空参构造方法 ;
* 2.2为所有属性提供setter方法。
*/
public User() {
super();
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(Integer password) {
this.password = password;
}
public void setList(List list) {
this.list = list;
}
@Override
public String toString() {
return “User [username=” + username + “, password=” + password +
“, list=” + list + “]”;
}
}
```
在文件User.java中,由于要使用构造注入,所以需要其有参和无参的构造方法。同时,为了输出时能够看到结果,还重写了其属性的toString()方法。
(2)在src/main/resources目录下,创建Spring配置文件beans5.xm,创建配置文件beans5.xml,在配置文件中通过构造注入和设值注入的方式装配User类的实例,如文件所示。文件 beans5.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!--1.使用构造注入方式装配User实例 -->
<bean id="user1" class="com.awen.assemble.User">
<constructor-arg index="0" value="柳小子" />
<constructor-arg index="1" value="123456" />
<constructor-arg index="2">
<list>
<value>"constructorvalue1"</value>
<value>"constructorvalue2"</value>
</list>
</constructor-arg>
</bean>
<!--2.使用设值注入方式装配User实例 -->
<bean id="user2" class="com.awen.assemble.User">
<property name="username" value="子小柳"></property>
<property name="password" value="654321"></property>
<!-- 注入list集合 -->
<property name="list">
<list>
<value>"setlistvalue1"</value>
<value>"setlistvalue2"</value>
</list>
</property>
</bean>
</beans>
在上述配置文件中,元素用于定义构造方法的参数,其属性index表示其索引(从0开始), value属性用于设置注入的值,其子元素来为User类中对应的list集合属性注入值。然后又使用了设值注入方式装配User类的实例,其中元素用于调用Bean实例中的setter方法完成属性赋值,从而完成依赖注入,而其子元素同样是为User类中对应的list集合属性注入值。
(3)在com.awen.assemble包中,创建测试类XmlBeanAssembleTest,在类中分别获取并输出配置文件中的user1和user2实例,如文件所示。文件 XmlBeanAssembleTest.java
package com.awen.assemble;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class XmlBeanAssembleTest {
public static void main(String[] args) {
// 加载配置文件
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("beans5.xml");
// 构造方式输出结果
System.out.println(applicationContext.getBean("user1"));
// 设值方式输出结果
System.out.println(applicationContext.getBean("user2"));
}
}
执行程序后,控制台的输出结果如下所示,
D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=3035:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.assemble.XmlBeanAssembleTest
User [username=柳小子, password=123456, list=["constructorvalue1", "constructorvalue2"]]
User [username=子小柳, password=654321, list=["setlistvalue1", "setlistvalue2"]]
Process finished with exit code 0
从运行结果可以看出,已经成功地使用基于XML装配的构造注入和设值注入两种方式装配了User实例。
OK , 到了现在 , 我们彻底不用再去程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
思考
user 对象是谁创建的 ?
【 user 对象是由Spring创建的 】
user 对象的属性是怎么设置的 ?
【user 对象的属性是由Spring容器设置的 】
这个过程就叫控制反转(IoC) :
控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
依赖注入 : 就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收
可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .
基于注解(Annotation)的装配
除了通过设值注入(Setter Injection)和构造注入(Constructor Injection)实现IoC,还可以通过Spring提供的注解方法实现IoC,这也是企业开发过程中最常用的一种IoC实现方式。
在Spring中,尽管使用XML配置文件可以实现Bean的装配工作,但如果应用中有很多Bean时,会导致XML配置文件过于臃肿,给后续的维护和升级工作带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。
Spring中定义了一系列的注解,常用的注解如下所示。
- @Component:可以使用此注解描述Spring中的Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
- @Repository:用于将数据访问层(DAO层)的类标识为Spring中的Bean,其功能与@Component相同。
- @Service:通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同。
- @Controller:通常作用在控制层(如Spring MVC的Controller),用于将控制层的类标识为Spring中的Bean,其功能与@Component相同。
- @Autowired:用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作。默认按照Bean的类型进行装配。
- @Resource:其作用与Autowired一样。其区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按实例名称进行装配;如果指定type属性,则按Bean类型进行装配;如果都不指定,则先按Bean实例名称装配,如果不能匹配,再按照Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException异常。
- @Qualifier:与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。在上面几个注解中,虽然@Repository、@Service与@Controller功能与@Component注解的功能相同,但为了使标注类本身用途更加清晰,建议在实际开发中使用@Repository、@Service与@Controller分别对实现类进行标注
下面,通过一个案例来演示如何通过这些注解来装配Bean。
(1)在chapter02模块的src/main/java目录下,创建一个com.awen.annotation包,在该包中创建接口UserDao,并在接口中定义一个save()方法,如文件所示。文件 UserDao.java
package com.awen.annotation;
public interface UserDao {
public void save();
}
(2)在com.awen.annotation包中,创建UserDao接口的实现类UserDaoImpl,该类需要实现接口中的save()方法,如文件所示。文件 UserDaoImpl.java
package com.awen.annotation;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImpl implements UserDao{
public void save(){
System.out.println("userdao...save...");
}
}
在文件UserDaoImpl.java中,首先使用@Repository注解将UserDaoImpl类标识为Spring中的Bean,其写法相当于配置文件中<bean id="userDao" class="com.awen.annotation.UserDaoImpl"/>
的编写。然后在save()方法中输出打印一句话,用于验证是否成功调用了该方法。
(3)在com.awen.annotation包中,创建接口UserService,在接口中同样定义一个save()方法,如文件所示。文件UserService.java
package com.awen.annotation;
public interface UserService {
public void save();
}
(4)在com.awen.annotation包中,创建UserService接口的实现类UserServiceImpl,该类需要实现接口中的save()方法,如文件所示。文件 UserServiceImpl.java
package com.awen.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService{
@Resource(name="userDao")
private UserDao userDao;
public void save() {
//调用userDao中的save方法
this.userDao.save();
System.out.println("userservice....save...");
}
}
在文件 UserServiceImpl.java中,首先使用@Service注解将UserServiceImpl类标识为Spring中的Bean,这相当于配置文件中<bean id="userService" class="com.itheima.annotation.UserServiceImpl"/>
的编写;然后使用@Resource注解标注在属性userDao上,这相当于配置文件中<property name="userDao" ref="userDao"/>
的写法;最后在该类的save()方法中调用userDao中的save()方法,并输出一句话。
(5)在com.awen.annotation包中,创建控制器类UserController,编辑后如文件所示。文件UserController.java
package com.awen.annotation;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller("userController")
public class UserController {
@Resource(name="userService")
private UserService userService;
public void save(){
this.userService.save();
System.out.println("userController...save...");
}
}
在文件UserController.java中,首先使用@Controller注解标注了UserController类,这相当于在配置文件中编写<bean id="userController" class="com.itheima.annotation.UserController"/>
;然后使用了@Resource注解标注在userService属性上,这相当于在配置文件中编写<property name="userService" ref="userService" />
;最后在其save()方法中调用了userService中的save()方法,并输出一句话。
(6)在src/main/resources目录下,创建配置文件beans6.xml,在配置文件中编写基于Annotation装配的代码,如文件所示。文件 beans6.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 使用 context 命名空间 ,在配置文件中开启相应的注解处理器 -->
<context:annotation-config />
<!--分别定义3个Bean实例 -->
<bean id="userDao" class="com.awen.annotation.UserDaoImpl" />
<bean id="userService"
class="com.awen.annotation.UserServiceImpl" />
<bean id="userController"
class="com.awen.annotation.UserController" />
</beans>
从上述代码可以看出,文件beans6.xml与之前的配置文件有很大不同。首先,在元素中,增加了第4行,第7行和第8行中包含有context的约束信息;然后通过配置<context:annotation-config />来开启注解处理器;最后分别定义了3个Bean对应所编写的3个实例。与XML装备方式有所不同的是,这里不再需要配置子元素<property>
。
上述Spring配置文件中的注解方式虽然较大程度简化了XML文件中Bean的配置,但仍需要在Spring配置文件中一一配置相应的Bean,为此Spring注解提供了另外一种高效的注解配置方式(对包路径下的所有Bean文件进行扫描),其配置方式如下。
<context:component-scan base-package="Bean所在的包路径" />
所以可以将上述文件文件 beans6.xml中第9~16行代码进行如下替换(推荐)。
<!--使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析-->
<context:component-scan base-package="com.awen.annotation" />
(7)在com.awen.annotation包中,创建测试类AnnotationAssembleTest,在类中编写测试方法并定义配置文件的路径,然后通过Spring容器加载配置文件并获取UserController实例,最后调用实例中的save()方法,如文件所示。文件 AnnotationAssembleTest.java
package com.awen.annotation;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationAssembleTest {
public static void main(String[] args) {
// 定义配置文件路径
String xmlPath = "com/awen/annotation/beans6.xml";
// 加载配置文件
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(xmlPath);
// 获取UserController实例
UserController userController =
(UserController) applicationContext.getBean("userController");
// 调用UserController中的save()方法
userController.save();
}
}
总是出错 一叶障目
执行程序后,控制台的输出结果如图所示。
userdao...save...
userservice....save...
userController...save...
从运行结果可以看到,Spring容器已成功获取了UserController的实例,并通过调用实例中的方法执行了各层中的输出语句,这说明已成功实现了基于Annotation装配Bean
小提示上述案例中如果使用@Autowired注解替换@Resource注解,也可以达到同样的效果。
提示: 除了可以像示例中通过元素来配置Bean外,还可以通过包扫描的形式来配置一个包下的所有Bean:
<context:component-scan base-package=“com.awen.annotation” />
自动装配
虽然使用注解的方式装配Bean,在一定程度上减少了配置文件中的代码量,但是也有企业项目中,是没有使用注解方式开发的,那么有没有什么办法既可以减少代码量,又能够实现Bean的装配呢?答案是肯定的,Spring的元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。所谓自动装配,就是将一个Bean自动地注入到其他Bean的Property中。autowire属性有5个值,其值及说明如表所示。表元素的autowire属性值及说明
自动装配,使用方式如下:
修改上一节UserServiceImple和UserController,分别增加类属性的setter方法;
修改Spring配置文件beans6.xml,将配置文件修改成自动装配形式,也就是使用autowire属性配置Bean;
重新测试程序。
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 使用 context 命名空间 ,在配置文件中开启相应的注解处理器 -->
<!-- <context:annotation-config />-->
<!-- <!–分别定义3个Bean实例 –>-->
<!-- <bean id="userDao" class="com.awen.annotation.UserDaoImpl" />-->
<!-- <bean id="userService"-->
<!-- class="com.awen.annotation.UserServiceImpl" />-->
<!-- <bean id="userController"-->
<!-- class="com.awen.annotation.UserController" />-->
<!--使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析-->
<!-- <context:component-scan base-package="com.awen.annotation" />-->
<!-- 使用bean元素的autowire属性完成自动装配 -->
<bean id="userDao"
class="com.awen.annotation.UserDaoImpl" />
<bean id="userService"
class="com.awen.annotation.UserServiceImpl" autowire="byName" />
<bean id="userController"
class="com.awen.annotation.UserController" autowire="byName"/>
</beans>
上述配置文件中,用于配置userService和userController的元素中除了id和class属性外,还增加了autowire属性,并将其属性值设置为byName。在默认情况下,配置文件中需要通过ref来装配Bean,但设置了autowire="byName"后,Spring会自动寻找userService Bean中的属性,并将其属性名称与配置文件中定义的Bean做匹配。由于UserServiceImpl中定义了userDao属性及其setter方法,这与配置文件中id为userDao的Bean相匹配,所以Spring会自动地将id为userDao的Bean装配到id为userService的Bean中。执行程序后,控制台的输出结果如下所示。 从运行结果可以看出,使用自动装配同样完成了依赖注入
D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=5574:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.annotation.AnnotationAssembleTest
userdao...save...
userservice....save...
userController...save...
Process finished with exit code 0
手动装配
自动装配
- 自动装配是Spring满足bean依赖的一种方式!
- Spring会在上下文中自动寻找,并自动给bean装配属性!
在Spring中有三种装配的方式:
- 在xml中显式配置;
- 在java中显式配置;
- 隐式的自动装配bean 重要
Autowired 自动装配
ByName自动装配
ByType自动装配
小结:
- byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
- byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
使用注解实现自动装配
jdk1.5支持注解,Spring2.5开始支持注解。
要使用注解须知:
导入约束:context约束。
配置注解的支持:context:annot-config/
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
@Autowired
直接在属性上使用即可!也可以在set方式上使用!
使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IoC(Spring)容器中存在,且符合名字byName!
科普:
@Nullable 字段标记了这个注解,说明这个字段可以为null
public People(@Nullable String name){
this.name = name;
}
public @interface Autowired {
boolean required() default true;
}
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解@Autowired完成的时候,我们可以使用@Qualifier(value=“xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
@Resource注解
小结:
@Resource和@Autowired的区别:
- 都是用来自动装配的,都可以放在属性字段上;
- @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】
- @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!
- 执行顺序不同:@Autowired通过byType的方式实现,@Resource默认通过byName的方式实现。
在spring4之后,要使用注解开发,必须要保证aop的包导入了。
使用注解需要导入context约束,增加注解的支持!
<!--指定要扫描的包,这个包下的注解会生效-->
<context:component-scan base-package="com.kuang.pojo"/>
bean
属性如何注入
//等价于<bean id="user" class="com.kuang.pojo.User"/>
//@Component 组件
@Component
public class User {
//相当于<property name="name" value="小憨批"/>
public String name;
@Value("小憨批")
public void setName(String name){
this.name = name;
}
}
衍生的注解
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!
- dao【@Repository】
- service【@Service】
- controller【@Controller】
这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean!
自动装配
-@Autowired:自动装配通过类型,名字
如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value="xxx")
-@Nullable:字段标记了这个注解,说明这个字段可以为null
-@Resource:自动装配通过名字,类型
作用域
@Scope("singleton")
public class User {
//相当于<property name="name" value="小憨批"/>
public String name;
@Value("小憨批")
public void setName(String name){
this.name = name;
}
}
小结
xml与注解:
- xml更加万能,适用于任何场合!维护简单方便。
- 注解,不是自己的类使用不了,维护相对复杂!
xml与注解最佳实践:
- xml用来管理bean;
- 注解只负责完成属性的注入;
- 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持。
<!--指定要扫描的包,这个包下的注解会生效-->
<context:component-scan base-package="com.awen"/>
<context:annotation-config/>
【Spring】Spring中的Bean - 5、Bean的装配方式(XML、注解(Annotation)、自动装配)的更多相关文章
- java 从spring容器中获取注入的bean对象
java 从spring容器中获取注入的bean对象 CreateTime--2018年6月1日10点22分 Author:Marydon 1.使用场景 控制层调用业务层时,控制层需要拿到业务层在 ...
- 从spring容器中取出注入的bean
从spring容器中取出注入的bean 工具类,代码如下: package com.hyzn.fw.util; import org.springframework.beans.BeansExcept ...
- Spring框架中的单例bean是线程安全的吗?
不,Spring框架中的单例bean不是线程安全的.
- Spring 框架中的单例 bean 是线程安全的吗?
不,Spring 框架中的单例 bean 不是线程安全的.
- spring学习总结——高级装配学习二(处理自动装配的歧义性)
我们已经看到如何使用自动装配让Spring完全负责将bean引用注入到构造参数和属性中.自动装配能够提供很大的帮助.不过,spring容器中仅有一个bean匹配所需的结果时,自动装配才是有效的.如果不 ...
- 关于 Spring Boot 中创建对象的疑虑 → @Bean 与 @Component 同时作用同一个类,会怎么样?
开心一刻 今天放学回家,气愤愤地找到我妈 我:妈,我们班同学都说我五官长得特别平 妈:你小时候爱趴着睡觉 我:你怎么不把我翻过来呢 妈:那你不是凌晨2点时候出生的吗 我:嗯,凌晨2点出生就爱趴着睡觉呗 ...
- Spring课程 Spring入门篇 3-4 Spring bean装配(上)之自动装配
课程链接: 1 自动装配的方式 2 自动装配实现 1 自动装配的方式 根据反射的机制 1.1 byName根据属性名自动装配,类似于依赖注入的set注入.(如果找不到set属性中的bean,如果tes ...
- Spring 容器可以在自动装配相互协作的 bean 之间的关系,使用autowire属性定义指定自动装配模式。
使用setter方法java public class TextEditor { private SpellChecker spellChecker; public void setSpellChec ...
- Spring中@Autowired注解与自动装配
1 使用配置文件的方法来完成自动装配我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. ...
随机推荐
- MVC部署出现403.14问题记录
1.问题截图 2.解决办法有几种 1)在system.webServer下增加,这种是不推荐的. <modules runAllManagedModulesForAllRequests=&quo ...
- String概述
String的基本特性 String是字符串,使用一对引号("")包装. String声明是final的,不可被继承. String实现了Serializable接口,表示字符串是 ...
- JVM虚拟机(二):字节码执行引擎
运行时栈帧结构 栈帧是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈的栈元素.栈帧存储了方法的局部变量表.操作数栈.动态链接.和方法返回地址等信息. ...
- js下 Day18、综合案例
一.分页 效果图: 功能思路分析: 分页就是将所有的数据按指定条数分成若干份: 假如有24条数据,每页只显示5条,则需要分成Math.ceil(24 / 5) = 5页; 每次只显示1页数据,所以需要 ...
- pytest接口测试轻松入门
通过Postman请求结果如下图: 那我们怎么用pytest进行测试呢? 在接口测试,我们要用到requests包,实现代码如下: import pytest import allure import ...
- Python基础入门:注释、变量、运算符与数据类型
一.为什么要学习python? python的特点 python作为一门脚本语言,在越来越多的行业和领域发挥着重大作用,比如机器学习.网站开发.数据分析.爬虫.自动化测试. 同时,python具备以下 ...
- 论文阅读: A Review of Robot Learning for Manipulation: Challenges, Representations, and Algorithms
机器人学习操纵综述:挑战,表示形式和算法 1.介绍 因此,研究人员专注于机器人应如何学习操纵周围世界的问题. 这项研究的范围很广,从学习个人操作技巧到人类演示,再到学习适用于高级计划的操作任务的抽象描 ...
- 数据库SQL调优的几种方式 EFcore读的情况下使用 AsNoTracking非跟踪查询
不要用GUID 当主键 没有规律 可以用雪花ID DBA 优化法则 硬件资源是根本,DBA是为了充分利用硬件资源 一般清空下可以不使用外键 可以提高性能 合理使用临时表 临时表分页; 一些查询语句加w ...
- ASP.NET Core 3.1使用JWT认证Token授权 以及刷新Token
传统Session所暴露的问题 Session: 用户每次在计算机身份认证之后,在服务器内存中会存放一个session,在客户端会保存一个cookie,以便在下次用户请求时进行身份核验.但是这样就暴露 ...
- 使用CodeSmith编写ADO.Net三层
说明 自本文发布日起,发现和完善了编写的CodeSmith几处代码. 故,不再直接在文章添加代码,最新代码参见GitHub https://github.com/catbiscuit/CodeSmit ...