1.Bean和对象的区别:
Bean是一个对象 但是 对象不一定是Bean
比方说创建一个Spring容器 通过这个容器中的getBean方法可以获取这个Bean
代码实例:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = applicationContext.getBean("userService",UserService.class);
这段代码获取的就是Bean的实例 反观 对象是不是Bean? 再来看这段代码
UserService userService = new UserService();
这段代码是通过new的方式创建出来的 也很容易看出 它是一个对象 没有任何Bean的操作
所以得出结论 Bean是一个对象 因为通过getBean的方法获取的这个实例 可以调用这个类中的任意
方法 而正常通过new的方式来创建的对象它就不是一个Bean 因为它除了new以外通过无参构造器
的方式来创建出这个对象 但是没有任何的Bean操作 所以 Bean是一个对象 对象不一定是Bean
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class)
通过这样new的一个方式来创建出Spring的容器 实质上 无论是SpringBoot亦或者是SpringMVC中
最终执行的都是这段代码 也就是说我们在使用Spring来进行构造Bean实例或者是对象的时候也都
是间接性的调用了这段代码 然后通过这个对象来调用getBean方法
既然Bean是对象 那Spring是怎么创建的这个对象?再来看这段代码
UserService userService = applicationContext.getBean("userService",UserService.class);
通过反射的这样一个方式返回值是一个UserService 并且在UserService这个类中加入了@Component
注解 学过Spring的都知道 这个注解的意思就是把当前类放到Spring容器中让它去进行实例化(Bean)既然通过这个注解去获取的Bean 那肯定要先创建出这个类对象才能获取到这个Bean
在Java中通常创建对象的方式是这样的:UserService.class ------->无参构造器----->对象
2.Bean是如何赋值的
当这个Bean创建完成之后是可以通过这个Bean对象取值的 获取方法 等等一些操作 而我们通过无参
构造器的这种方式创建出的对象它是没有值的 那么通过Bean的方式去获取对象 为什么就会有值
1)首先为什么通过Bean的方式获取对象就会有值
我们正常创建对象 都会有一个构造器 即使我们不写 Java类中也会默认的去加载一个无参的构造器
以此来帮助我们去创建出一个对象 同样 Spring在帮我们创建这个Bean对象的时候也会有一个操作
叫依赖注入(@Autowired)
2)那么Spring是怎么通过依赖注入的方式去赋值?
在创建对象的时候每个类都会加载一个默认的无参构造器 依赖注入就是通过这个无参构造器得到对象
在这个对象中那些加了@Autowired注解的属性由Spring去赋值
在Spring的角度去想 既然拿到了UserService对象 那么Spring就会去给那些加了@Autowired注解的属
性去赋值 不可能给这个对象中的所有属性去赋值 只会给加了@Autowired注解的属性去赋值如下代码
@Component
public class UserService{
@Autowired
private OrderService orderService;
}
3)那如何去找那些加了@Autowired注解的属性并赋值?代码示例:
//首先通过getBean的方法来获取这个Bean对象
UserService userService = applicationContext.getBean("userService",UserService.class);
for(Field field : userService.getClass().getField()){//遍历这个对象的属性
if(field.isAnnotationPresent(Autowired.class)){//判断属性是否含有Autowired
field.set(); //赋值操作
}
}
那么在依赖注入之后还会有这样的步骤
4)UserService.class ----->无参构造器----->对象----->依赖注入----->初始化前----->初始化----->初始化
后----->Bean
在依赖注入后会去执行初始化的操作
什么是初始化前 举个例子 如下代码
@Component
public class UserService{ //用户服务
@Autowired
private User admin;//管理员
}
5)在这个UserService中加入了User的类 如果此时想自动获取这个admin的信息 该如何操作?
通过之前的代码不难看出 虽然这个admin加了@Autowired注解可以获取到值 但是这个信息并不是想
要的值 什么意思? 就是如果我们想获取这个admin的信息 比方说 用户名 密码 权限等这类信息
在正常的逻辑下 这个admin信息是需要我们到DBMS中查到后的数据来返回给这个User对象
那如何通过我们在数据库中查到的值可以直接通过这个对象调用?
那在这里肯定是需要定义一个方法并且让这个方法自动去执行 这样的话就可以通过调用这个对象可以
自动的获取我们在数据库中查到的值
如何让它去自动执行?代码示例:
UserService userService = applicationContext.getBean("userService",UserService.class);
for(Method method : User.getClass().getMethod()){//遍历这个对象的方法
if(method.isAnnotationPresent(PostConstruct.class)){//判断方法是否含有PostConstruct注解
method.invoke(); //如果有这个注解就去执行
}
}
也就是说在需要让它去自动执行的方法加入@PostConstruct注解即可
通过上述代码就完成了初始化前的一个操作
6)什么是初始化:以5)步骤操作为示例 还有一种方法 代码示例:
@Component
public class UserService implements InitializingBean{
@Override
public void afterPropertiesSet() throws Exception{
//到DBMS中查询admin数据的操作
}
}
当执行到初始化的这步操作的时候 会先对当前对象进行一次判断 判断当前对象是否实现了
InitializingBean这个接口 如果实现了返回true 并将这个对象强转为InitializingBean类型 这时
Spring就会自动调用afterPropertiesSet()这个方法 这样就完成了初始化的一个操作
7)初始化后:AOP的操作