基本说明:
基于注解配置bean,也可以实现自动装配,使用的注解是:@AutoWired或者@Resource
@AutoWired 的规则说明
(1)在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按类型),则使用该bean装配
(2)如果待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值进行查找,找到就装配,找不到就抛异常
@Resource 的规则说明
(1)@Resource 有两个属性比较重要,分别是name和type
Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType的自动注入策略
(2)如果@Resource没有指定name或者type,则先使用ByName注入策略,如果匹配不上,再使用byType策略,如果都不成功就会报错
不管是@AutoWired 还是 @Resource,都保证属性名是规范的写法就可以注入。
除了有特殊要求,一般推荐使用@Resource
应用实例需求:
UserService:
package com.li.component;
import org.springframework.stereotype.Service;
/**
* @author 李
* @version 1.0
* @Service 标识该类是一个Service类/对象
*/
@Service
public class UserService {
public void hi(){
System.out.println("UserService hi()...");
}
}
UserAction:
package com.li.component;
import org.springframework.stereotype.Controller;
/**
* @author 李
* @version 1.0
* @Controller 标识该类是一个控制器Controller,通常该类是一个Servlet
*/
@Controller
public class UserAction {
private UserService userService;
public void sayOk() {
System.out.println("UserAction 的 sayOk()");
userService.hi();
}
}
beans05.xml指定要扫描的包:
<context:component-scan base-package="com.li.component"/>
测试类:
//通过注解来配置Bean
@Test
public void setProByAutowired() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
UserAction userAction = ioc.getBean("userAction", UserAction.class);
System.out.println("userAction=" + userAction);
userAction.sayOk();
}
如下,当运行到userAction.sayOk();时抛出空指针异常:
这是因为userAction中的属性userService指向null,即没有正确的装配UserService对象。
添加@Autowired注解:
在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按照类型组装),则使用该bean装配
@Controller
public class UserAction {
//在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按类型),则使用该bean装配
@Autowired
private UserService userService;
public void sayOk() {
System.out.println("UserAction 的 sayOk()");
userService.hi();
}
}
运行结果如下,成功调用了userService.hi()方法,说明userService对象已经成功装配:
现在我们在beans05.xml容器中再配置两个UserService对象
spring允许同时使用xml配置文件和注解的方式配置bean
<context:component-scan base-package="com.li.component"/>
<!--配置两个UserService对象-->
<bean class="com.li.component.UserService" id="userService200"/>
<bean class="com.li.component.UserService" id="userService300"/>
此时在ioc容器中就有三个UserService对象:
(1)对于自动扫描进去的UserService对象,它的id为它的类名(首字母小写)。
(2)在xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)
现在我们重新运行测试方法:
//通过注解来配置Bean
@Test
public void setProByAutowired() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
UserAction userAction = ioc.getBean("userAction", UserAction.class);
System.out.println("userAction=" + userAction);
userAction.sayOk();
}
问题一:运行会不会报错?
问题二:@AutoWired注解的属性进行自动装配的时候,装配的是哪一个UserService对象?
@Autowired
private UserService userService;
答案一:没有报错
答案二: 在@AutoWired注解中,如果待装配的类型对应的bean在IOC容器中有多个,则使用待装配属性的名称作为id值进行查找,找到就装配,找不到就抛异常。因此装配的是ioc容器中id与待装配属性的属性名一致的对象。
使用UserAction和UserService说明,我们在UserAction类的属性userService400添加@Resource注解,并给@Resource注解添加name属性值=“userService”
package com.li.component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
/**
* @author 李
* @version 1.0
* @Controller 标识该类是一个控制器Controller,通常该类是一个Servlet
*/
@Controller
public class UserAction {
@Resource(name = "userService")
private UserService userService400;
public void sayOk() {
System.out.println("UserAction 的 sayOk()");
userService400.hi();
}
}
同时,我们在配置文件beans05.xml文件中又配置了两个UserService对象:
<context:component-scan base-package="com.li.component"/>
<!--配置两个UserService对象-->
<bean class="com.li.component.UserService" id="userService200"/>
<bean class="com.li.component.UserService" id="userService300"/>
也就是说,在beans05.xml文件对应的ioc容器中,此时一共有三个UserService对象:
(1)@Resource注解中配置的名为userService的对象
(2)在xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)
那么在UserAction类的userService400属性中,spring给此属性自动装配的是三个中的哪一个对象呢?
答:id名为“userService”的对象。因为Spring将@Resource注解的name属性解析为bean的名字。 至于UserAction类的属性是什么名字无所谓。
Spring将@Resource注解的type属性则解析为bean的类型。
现在我们将UserAction类中的注解改为type=UserService.class,表示按照UserService.class的类型来进行装配
@Resource(type = UserService.class)
private UserService userService400;
这意味着在ioc容器中,只能有一个UserService类型的对象。如果配置了多个,就会报错:

问题:如果我们在@Resource注解的属性下什么都不写,会如何装配对象?
@Resource
private UserService userService400;
分析如下:现在ioc容器中,还是有三个UserService对象:
(1)@Resource注解中配置的对象(当没有指定name时,该对象对应的id就是“userService”)
(2)xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)
如果@Resource没有指定name或者type,则先使用ByName注入策略,如果匹配不上,再使用byType策略,如果都不成功就会报错。
这里首先使用ByName策略,即匹配userService400,匹配不上后又使用byType策略,显然这里有三个对象,不符合类型匹配。也就是说两种策略都匹配失败,因此结果是:运行出错。
如待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值再进行查找,找到就装配,找不到就抛异常 [ByName策略]
可以使用@Autowired和@Qualifier两个注解配合,可以指定装配对象的id值(注意这个id的对象要在ioc容器中存在)
@Autowired
@Qualifier(value = "userService200")
private UserService userService;
基本说明:
应用实例
现有多个类,关系如下:
如上图,如果我们想要在BookService类中使用BookDao属性对象,或者要在PhoneService类中使用PhoneDao对象,传统方法是将 PhoneDao /BookDao自动装配到 BookService/PhoneSerive 中。
但是,当这种继承关系多起来时,即要自动装配的属性多起来时,这种配置方式就显得比较麻烦。因此我们可以使用 spring 提供的泛型依赖注入。
下面模拟图中的类:
Javabean-Phone:
package com.li.depeinjection;
/**
* @author 李
* @version 1.0
*/
public class Phone {
}
Javabean-Book:
package com.li.depeinjection;
/**
* @author 李
* @version 1.0
*/
public class Book {
}
自定义泛型类BaseDao:
package com.li.depeinjection;
/**
* @author 李
* @version 1.0
* 自定义泛型类
*/
public abstract class BaseDao<T> {
public abstract void save();
}
BookDao继承BaseDao,指定泛型Book,并添加@Repository注解
package com.li.depeinjection;
import org.springframework.stereotype.Repository;
/**
* @author 李
* @version 1.0
*/
@Repository
public class BookDao extends BaseDao<Book> {
@Override
public void save() {
System.out.println("BookDao save()");
}
}
PhoneDao同样继承BaseDao,指定泛型Phone,并添加@Repository注解
package com.li.depeinjection;
import org.springframework.stereotype.Repository;
/**
* @author 李
* @version 1.0
*/
@Repository
public class PhoneDao extends BaseDao<Phone>{
@Override
public void save() {
System.out.println("PhoneDao save()");
}
}
自定义泛型类BaseService:
package com.li.depeinjection;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author 李
* @version 1.0
* 自定义泛型类
*/
public class BaseService<T> {
@Autowired
private BaseDao<T> baseDao;
public void save() {
baseDao.save();
}
}
BookService继承BaseService,指定泛型Book,并添加@Service注解
package com.li.depeinjection;
import org.springframework.stereotype.Service;
/**
* @author 李
* @version 1.0
*/
@Service
public class BookService extends BaseService<Book> {
//并没有写属性
}
PhoneService也继承BaseService,指定泛型Phone,并添加注解@Service
package com.li.depeinjection;
import org.springframework.stereotype.Service;
/**
* @author 李
* @version 1.0
*/
@Service
public class PhoneService extends BaseService<Phone>{
//并没有写属性
}
在配置文件beans06.xml中配置要扫描的包:
<context:component-scan base-package="com.li.depeinjection"/>
这意味着在com.li.depeinjection包下,添加了四种注解的类将会被进行扫描,在这里就是PhoneService类、BookService类、PhoneDao类、BookDao类
@Controller /@Service/ @Repository/ @Component
现在我们来进行测试:
//通过泛型依赖来配置Bean
@Test
public void setProByDependencyInjection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");
System.out.println("ok");
}
在语句System.out.println("ok");旁打上断点,点击debug,可以看到在ioc容器中已经有四个对象:
打开ioc-->beanFactory-->singletonObjects-->table属性,展开phoneService对象,可以看到该对象已经自动装载了PhoneDao类型的对象!!
这意味着我们通过泛型依赖注入,可以自动装配需要的对象,不必像之前一样一个个地为属性添加注解。
现在我们获取phoneService对象,调用该对象的save()方法:
//通过泛型依赖来配置Bean
@Test
public void setProByDependencyInjection() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans06.xml");
PhoneService phoneService = ioc.getBean("phoneService", PhoneService.class);
phoneService.save();
System.out.println("ok");
}
因为PhoneService类中没有实现save方法,因此在运行的时候会调用父类BaseService的save()方法,而BaseService的save()方法中又调用了baseDao属性的save()方法.
我们在上图可以知道baseDao的实际对象是PhoneDao类型,根据动态绑定,最终调用了PhoneDao类中的save()方法:
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev
我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li
我有一个任务列表(名称、starts_at),我试图在每日View中显示它们(就像iCal)。deftodays_tasks(day)Task.find(:all,:conditions=>["starts_atbetween?and?",day.beginning,day.ending]end我不知道如何将Time.now(例如“2009-04-1210:00:00”)动态转换为一天的开始(和结束),以便进行比较。 最佳答案 deftodays_tasks(now=Time.now)Task.find(:all,:conditio
什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一
ruby1.9.3dev(2011-09-23修订版33323)[i686-linux]轨道3.0.20最近为什么在与DateTimeonRails相关的RSpecs项目上工作我发现在给定日期以下语句发出的值date.end_of_day.to_datetime和date.to_datetime.end_of_day虽然它们表示相同的日期时间,但比较时返回false。为了确认这一点,我打开了Rails控制台并尝试了以下操作1.9.3dev:053>monday=Time.now.monday=>2013-02-2500:00:00+05301.9.3dev:054>monday.cla
文章目录前言一、Elasticsearch版本介绍二、客户端种类三、客户端与版本兼容性四、引入Elasticsearch依赖包五、客户端配置六、Elasticsearch使用前言ElasticSearch是Elastic公司出品的一款功能强大的搜索引擎,被广泛的应用于各大IT公司,它的代码位于https://github.com/elastic/elasticsearch,目前是一个开源项目。ElasticSearch公司的另外两个开源产品Logstash、Kibana与ElasticSearch构成了著名的ELK技术栈。。他们三个共同形成了一个强大的生态圈。简单地说,Logstash负责数据
有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N
如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1. 创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1. 创建SpringBoot项目 打开IDEA,选择NewProject创建项目。 填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。 选择springboot版本以及需要的包,此处只选择了springweb。 此处需特别注意,若你使用的是jdk1