Spring中BeanFactory Ioc AOP ApplicationContext怎么去理解?
###### IOC:
1.可插拔。可以通过注释掉@Repository实现拔一个bean,实现拔。重写一个bean加上注释@Repository来替换原来的bean,实现插。
2.bean生命周期的管理
在bean中实现@PostCountrust,让spring在实现构造方法后执行此方法
在bean中实现@PreDestrory,让spring在对象销毁前调用此方法
3.还可以定义作用域@Scope()
######Bean Factory
ApplicationContext是BeanFactory的子类,,Spring通过BeanFactory来进行bean的管理。
开发Spring的人员才可能会用BeanFactory,一般developer只用ApplicationContext。
ApplicationContext.getBean()是可以通过类名(String s 但它获得是一个object,而不具有类型)或者类型(Object.class)来获取一个bean,当然也可以同时进行。是@AtuoWired的手动实现。自定义类需要实现ApplicationContextWare接口。
public class Example implements ApplicationContextWare{
private applicationContext;
@Override
public void setApplicationContext(Application applicationContext) throws BeansException {
this.applicationContext = applicationContest;
}
@Test
public void testApplication(){
Mybean bean = applicationContext.getBean(Mybean.class);
//返回一个object
Mybean bean = applicationContext.getBean("myBean");
Mybean bean = applicationContext.getBean("myBean",Mybean.class);
}
}
###### AOP
AOP面向切面编程,可以理解为一个beanA(Aspect)可以影响多个beanB(Target),这些beanB提供一个方法(JoinPoint)给MyAaspect让其在某些时机触发(Advice,描述发生的时机)来解决这些bean的公共的一个或一些问题(PointCut,描述这些问题的地点),比如记日志,比如统一管理事务。
如何让Aspect与Target产生关联?
- Target给出一个JoinPoint
- Aspect.advice()在以下三种情况下织入JoinPoint
- 编译时,用特殊编译器
- 类加载时,用特殊的类加载器
- 运行时,为目标生成代理对象
SpringAop采用第三种方式,有接口采用JDK动态代理,无接口采用CGLIB动态代理
<!--这个包允许你用注解的方式使用AOP功能-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>{version}</verison>
</dependency>
aop的包在spring-starter引入时就引入了,但只能通过原生方式实现AOP(未实操)
@Component
@Aspect
public class MyAaspect {
//* cn.edu.swpu.example.service.*.*(..) 意思为指定包下的所有类,所有返回类型的带有所有形参的所有方法。
@PointCut("excution(* cn.edu.swpu.example.service.*.*(..))")
private void serviceAccess() {
}
//@After()
//@AfterThrowing()
//@AfterReturning() 在After()之前
//在方法执行前执行
@Before ("serviceAccess()")
private void before(){
System.out.println("log before");
}
}
手动使用ProceedingJoinPoint,用around注解,功能更强大,但犯错后影响范围也大,不是必要情况不推荐。
//另一种方式,使用ProceedingJoinPoint
@Around("serviceAccess()")
public Object log(ProceedingJoinPoint joinPoint){
Object obj = null;
try{
System.out.println("log before")
//调用目标组件的方法 返回一个object
obj = joinPoint.proceed();
System.out.println("log afterRunning");
} catch(Throwalble throwalbe) {
System.out.println("log afterThrowing");
}finally{
System.out.println("log after");
}
return obj;
}
(本人技艺不精,学识肤浅,若有错漏,欢迎指正)