Spring
Spring
Spring不能直接使用注解,需要先开启注解
<!--在spring-context中配置--> <!--开启spring注解功能--> <context:annotation-config></context:annotation-config> <!--选择扫描包的路径 扫描@component等注解修饰的类 --> <context:component-scan base-package="com.spring"></context:component-scan>
spring4后只需要开启扫描了,context:component-scan标签既开启注解,又开启扫描
bean生成
生成bean,交给Spring容器管理 :注解、xml
使用注解必须搭配xml(component-scan标签)或配置类(@ComponentScan、@Configuration)
Spring Boot就是使用Java configuration(配置类)配置信息
@service等注解生成bean需要额外扫描操作,@ComponentScan注解只能使用在有@Configuration配置注解的地方,因为component-scan标签必须存在于xml配置文件中;而在脱离xml使用时,需要使用带有在@Configuration配置注解上。并不局限与一定是 @Configuration也可以是
@Service //注解配置bean
public class SysCustomerServiceImpl extends AbstractService implements SysCustomerService {
@Autowired
private SysCustomerMapper sysCustomerMapper;
}
//上边会自动生成一个name为sysCustomerServiceImpl的bean
//等同于以前xml配置法在applicationContext.xml中配置:
<bean name="sysCustomerServiceImpl" class="com.sinosig.sl.slts.soa.impl.SysCustomerServiceImpl"></bean>
DI可以注入不同类型,@Autowired 与@Resource装配bean
@Autowired 与@Resource的区别
- @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
- @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
- @Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。
作用域
Bean的作用域Spring 3中为Bean定义了5中作用域,分别为singleton(单例)、prototype(原型)、request、session和global session,5种作用域说明如下:
- singleton:单例模式,Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象。Singleton作用域是Spring中的缺省作用域,也可以显示的将Bean定义为singleton模式,配置为:
配置实例: <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 或者 <bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>
- prototype:原型模式,每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态,而singleton全局只有一个对象。根据经验,对有状态的bean使用prototype作用域,而对无状态的bean使用singleton作用域。
- request:在一次Http请求中,容器会返回该Bean的同一实例。而对不同的Http请求则会产生新的Bean,而且该bean仅在当前Http Request内有效。,针对每一次Http请求,Spring容器根据该bean的定义创建一个全新的实例,且该实例仅在当前Http请求内有效,而其它请求无法看到当前请求中状态的变化,当当前Http请求结束,该bean实例也将会被销毁。
- session:在一次Http Session中,容器会返回该Bean的同一实例。而对不同的Session请求则会创建新的实例,该bean实例仅在当前Session内有效。,同Http请求相同,每一次session请求创建新的实例,而不同的实例之间不共享属性,且实例仅在自己的session请求内有效,请求结束,则实例将被销毁。
- global Session:在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。
@Lookup
假设一个单例的Bean A需要引用一个非单例模式的Bean B,那么在每次引用B的时候都想拿到一个新的B,该怎么做?要知道,Bean A是单例模式的,只会被创建一次,注入一次属性,也就是说,即使B是property模式,那也是只会一个相同的B,因为A只会被注入一次。
解决办法
1.让bean A通过实现ApplicationContextAware来感知applicationContext(即可以获得容器上下文),从而能在运行时通过ApplicationContext.getBean(String beanName)的方法来获取最新的bean B。
2. 使用Spring的Lookup注解:
需要注意的是@Lookup只能注解在方法上,这个时候可以注解在一个抽象方法上。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix