spring的注入方式
- 构造方法注入
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
- setter注入
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<property name="userDao" ref="userDaoMyBatis"></property>
</bean>
- 基于注解的注入
有四种注解可以注册bean:
@Component //可以用于注册所有bean
@Repository //主要用于注册dao层的bean
@Controller //主要用于注册控制层的bean
@Service //主要用于注册服务层的bean
可以使用@Resource和@Autowired来描述依赖关系。可以写在字段上,也可以写在依赖方法上。
@Resource:名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
@Autowired:默认按类型装配。认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
@Autowired() @Qualifier("baseDao")
private BaseDao baseDao;
@Required用于检查该字段是否被被注入。如果没有会抛出异常。
SPRING的三种配置方式
- 基于XML的配置
<beans>
<bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
</beans>
- 基于注解的配置
首先要打开注解功能
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
- 基于Java的配置
首先,要在配置文件中打开扫描
<context:component-scan base-package="com.sjf.bean">
</context:component-scan>
然后定义spring配置类
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
上述代码等价于
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
注意,显然,不是我们每一次对MyService进行getbean时都调用该方法。实际上,只有第一次getbean时会调用MyService myService(),以后调用时,spring都会拦截该方法,在上下文找到已经存在的bean,然后返回。
ApplicationContext和BeanFactory接口
在Srping Ioc容器中,有BeanFactory和ApplicationContext两个系列,分别是:
实现BeanFactory接口的简单容器,具备最基本功能。
实现ApplicationContext接口的复杂容器,具备高级功能。
两个接口之间是有继承关系的,ApplicationContext的继承BeanFactory。常见的代码片段如下:
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
BeanFactory factory = (BeanFactory) context;
SPRING BEAN的生命周期管理
spring bean的生命周期管理就是指在
- 初始化之后调用的回调方法。
- 销毁之前调用的回调方法。
spring提供了四种方式来管理生命周期
- InitializingBean和DisposableBean回调接口
- 针对特殊行为的其他Aware接口
- Bean配置文件中的Custom init()方法和destroy()方法
- @PostConstruct和@PreDestroy注解方式
使用customInit()和 customDestroy()方法管理bean生命周期的代码样例如下:
<beans>
<bean id="demoBean" class="com.howtodoinjava.task.DemoBean"
init-method="customInit" destroy-method="customDestroy"></bean>
</beans>
同时,应该在bean中生命这个两个方法
package com.howtodoinjava.task;
public class DemoBean
{
public void customInit()
{
System.out.println("Method customInit() invoked...");
}
public void customDestroy()
{
System.out.println("Method customDestroy() invoked...");
}
}
SPRING BEAN的作用域
- singleton,默认的。单例模式,spring自身维护,保证不管收到多少请求,始终只有一个。
对于单例模式而言,由于所有线程共享一个实例,所以,要不你把这个bean设计为无状态的,比如说一般DAO,要么,就只能自行保证线程安全。
对于单例的spring bean,可以设置器lazy-init属性为true,则该实例不会随着spring启动就被启动,而是会等待第一次请求。 - prototype,保证为每一个请求返回一个新的实例
- request,为每一个来自客户端的网络请求创建一个新的实例
- Session,确保每一个session创建一个新的实例
##SPRING中的事件
Spring的ApplicationContext 提供了支持事件和代码中监听器的功能。spring支持的默认事件有如下几种
- ContextRefreshedEvent spring初始化或者刷新时出发
- ContextStartedEvent spring初始化完成后出发
- ContextStoppedEvent spring停止后触发,spring停止后可以重新启动。
- ContextClosedEvent spring关闭后触发,所有bean都被销毁,不可重新启动
- RequestHandledEvent 请求在经过DispatcherServlet时被触发
public class AllApplicationEventListener implements ApplicationListener < ApplicationEvent >
{
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent)
{
//process event
}
}
还可以通过扩展ApplicationEvent 类来开发自定义的事件。
public class CustomApplicationEvent extends ApplicationEvent
{
public CustomApplicationEvent ( Object source, final String msg )
{
super(source);
System.out.println("Created a Custom event");
}
}
事件接收者
public class CustomEventListener implements ApplicationListener < CustomApplicationEvent >
{
@Override
public void onApplicationEvent(CustomApplicationEvent applicationEvent) {
//handle event
}
}
调用applicationContext实例发送事件
CustomApplicationEvent customEvent = new CustomApplicationEvent(applicationContext, "Test message");
applicationContext.publishEvent(customEvent);
注意,所有接收事件的bean都必须由spring管理才行。
Spring中常见的类和接口
###ApplicationContext 通常的实现如下:
-
FileSystemXmlApplicationContext 项目路径下寻找xml配置文件
-
ClassPathXmlApplicationContext classPath 路径下找寻找配置xml文件
-
WebXmlApplicationContext 专门为web工程定制
ApplicationContext提供了事件机制,可以向注册为监听器的bean发送事件
Spring MVC
-
DispatcherServlet是Spring MVC的核心。它用来处理所有的HTTP请求和响应。
-
@Controller注解
在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到
@Controller
public class MyController {
@RequestMapping ( "/showView" )
public ModelAndView showView() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName( "viewName" );
modelAndView.addObject( " 需要放到 model 中的属性名称 " , " 对应的属性值,它是一个对象 " );
return modelAndView; //放回一个包含Model和View的对象。
}
}
一些常见配置
spring配置中context:annotation-config 与 context:component-scan 区别
1)context:annotation-config可以理解为注解解析器,解析诸如@autowired,@Resource之类的注解。前提是注解作用的类已经被注册到spring容器里。
2)context:component-scan除了包含context:annotation-config所有的功能之外还可以自动扫描和注册base-package下有诸如@component之类注解的类,并将其作为bean注册到spring容器里。
总结:有component-scan就不需要annotation-config了。