使用Spring创建一个对象
在Java语言中,创建一个对象很简单,举例:
public class UserService {
public void test(){
System.out.println(“11111”);
}
}
public class Test {
public static void main(String[] args) {
UserService userService = new UserService();
userService.test();
}
}
如上代码块,执行Test类中的main方法,就可以在控制台中输出“11111”;
把类交给Spring管理就需要借助 AnnotationConfigApplicationContext或者ClassPathXmlApplicationContext将我们的类先加载注入到Spring容器中,然后再通过Spring将类进行实例化然后当作Bean交给Spring管理;
以AnnotationConfigApplicationContext举例:
package com.xiaofanshu.service;
import org.springframework.stereotype.Component;
@Component
public class UserService {
public void test(){
System.out.println("11111");
}
}
以上代码,创建UserService类,加上@Component注解,Spring才会对该类进行管理;
package com.xiaofanshu;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("com.xiaofanshu")
public class AppConfig {
}
以上代码,创建配置类AppConfig,加上@ComponentScan注解,目的是设置Spring需要扫描那些包下的类;
package com.xiaofanshu;
import com.xiaofanshu.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();
}
}
写一个Test测试类,写一个main方法:
1、创建AnnotationConfigApplicationContext对象时解析AppConfig配置类,就会扫描com.xiaofanshu.service包下的类,如果发现包下面的类有@Component、@Service注解,Spring就会把这个类记录下来作为value放到一个BeanDefinitionMap中,同时Spring会将类对应的beanName作为key存入BeanDefinitionMap;
2、通过.getBean("userService"),可以找到UserService类,然后将UserService创建处理来(创建过程很复杂,不在此处赘述);
Bean的创建过程概述
在此说明,以下的描述只是帮助大家了解Bean创建过程需要经历的几个过程,每个过程中还会有许多步骤,后续会结合自己的学习和认识更新每个过程中做的事情;
重要的事情说三遍:不精确!不精确!不精确!
- 利用该类的构造方法来市实例化得到一个对象,如果类中有多个构造方法,Spring会使用推断构造方法进行选择最合适的构造方法进行对象创建;
- Spring会在得到对象后,判断该对象中是否存在使用了@Autowired注解的属性,把这些属性找出来进行赋值,进行依赖注入;
- 依赖注入之后,Spring会判断是否实现BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口,如果实现了,就表示当前对象必须实现该接口中定义的setBeanName()、setBeanClassLoader()、setBeanFactory()方法,Spring就会调用这些方法并传入相应的参数;
- Aware回调之后,Spring会判断该对象中是否实现了@PostConstruct,如果存在就会调用该对象的此方法;紧接着,Spring会判断对象是否实现了InitializingBean接口,如果实现了,就表示当前对行必须实现该接口中的afterPropertiesSet()方法,Spring就回调用当前对象中的afterPropertiesSet()方法;最后Spring会判断当前对象是否需要实现AOP,如果不需要直接结束,如果需要,则进行动态代理生成一个代理对象作为Bean;
小结
- 是否AOP的区别:
- 进行AOP,那么Bean就是UserService的代理类所实例化得到的对象,而并非UserService本身所得到的对象;
- 未进行AOP,那么Bean就是通过UserService类的构造方法实例化得到的对象;
- 单例Bean和原型Bean:
- 单例Bean,默认为单例,也可以通过@Scope("singleton")设置类为单例Bean;单例Bean,会将Bean作为value放入BeanDefinitionMap中,Key为beanName;通过getBean()就可以直接从BeanDefinitionMap中获取Bean对象;
- 原型Bean,可以通过@Scope("prototype")设置类为原型Bean;原型Bean不会存储到BeanDefinitionMap中,每次getBean()都会重新获取一个Bean对象;
- Spring的事务:
- Spring通过判断某个方法上是否加了@Transaction注解,加了在执行该方法的时候就回开启Spring的事务,此时这个方法对应的类的Bean对象就是代理对象;
- Spring事务是否生效,判断标准是,是否为代理对象直接调用的加了@Transaction注解的方法,是事务生效,反之不生效;
本篇文章,仅是本人在学习Spring源码过程中个人的一些笔记和理解,如有偏差,望大家指正;