1、Bean的实例化
1、构造方法实例化
2、静态工厂实例化
3、实例工厂实例化
2、Bean的作用域
在 Spring 官方文档中,共提到了 7 种不同的 Bean 作用域,分别是:
1、singleton(单例)
2、prototype(多例)
3、request(某个HTTP Request中)
4、session(某用户HTTP Session中)
5、globalSession(详解)
6、application(整个Web应用)
7、websocket(详解)
2.1、globalSession作用域
这个作用域就比较特殊了, globalSession 作用域的效果与 session 作用域类似,但是只适用于基于 portlet 的 web 应用程序中。 Portlet 规范定义了 globalSession 的概念,该概念在组成单个 Portlet Web 应用程序的所有 Portlet 之间共享(引用自 Spring 文档)。说实话,在看到这里之前,我从来没听说过 portlet 。我现在所学的,基本上都是基于 Servlet 的 web 应用程序,所有关于这个作用域,我也不理解。但是 Spring 文档中有提到一点,那就是 如果我们在基于Servlet的web应用程序中使用globalSession作用域,实际上容器使用session作用域进行处理 。
2.2、websocket作用域
websocket 是一种应用层的通信协议,它提供应用层的全双工通信。Spring 提供对 websocket 协议的支持,于是就有了这么一个作用域。若一个 bean 的作用域为 websocket ,则只作用于一次 websocket 通信,若连接被释放,则 bean 自然也会被销毁。
3、Bean的生命周期
- Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
- Bean实例化后对将Bean的引入和值注入到Bean的属性中
- 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法
- 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。
- 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。
- 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。
- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
4、Bean的装配方式
4.1、基于Xml配置的装配
比较过时的方式,项目中使用的少。
4.2、基于Annotation注解的装配
用在类上的注解
@Component(value="Bean名称") 可以用在任何组件类上边
@Repository(value="Bean名称") 可以用来数据访问层的实现类上
@Service(value="Bean名称") 可以用来业务逻辑层的类上
@Controller(value="Bean名称") 可以用来控制器层的类上
用在属性上的注解
@Autowired 根据Bean的类型进行装配,如果一个接口有多个实现类,类上边不能用这个注解。
@Resource(name= "Bean名称") 根据Bean的名称进行装配。
@Value(value = "数据值")
4.3、基于Annotation注解的例子
注解方式:侧重使用基于属性的注入,少用构造函数的注入。
applicationContext.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 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:component-scan base-package="cn.sjxy"/> </beans>
User代码:
@Component(value = "user") public class User { @Value(value = "XXX") private String name; @Value(value = "1534518XXXX") private String mobile; public String toString() { return "用户名:"+this.name+";手机号:"+this.mobile; } }
UserDao代码:
public interface UserDao { public void insert(User user); //添加用户 }
UserDao实现1代码:
@Repository(value = "userDaoImpl1") public class UserDaoImpl1 implements UserDao { @Override public void insert(User user) { System.out.println("用户["+user+"]被新增1"); } }
UserDao实现2代码:
@Repository(value = "userDaoImpl2") public class UserDaoImpl2 implements UserDao { @Override public void insert(User user) { System.out.println("用户["+user.toString()+"]被新增2"); } }
UserService代码:
@Service(value = "userService") public class UserService { @Resource(name="userDaoImpl1") private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } //添加用户 public void addUser(User user) { userDao.insert(user); } }
测试代码:
public class SpringTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取用户 User user = (User)context.getBean("user"); System.out.println(user.toString()); //获取用户业务类 UserService userService = (UserService)context.getBean("userService"); userService.addUser(user); } }