Spring官方文档链接
本篇文章用来记录spring中的ioc和aop使用以及注意事项
Spring IOC
spring ioc 容器初始接口为public interface BeanFactory,其中包含获取容器对象方法
其主要实现抽象类为AbstractApplicationContext,观察其内部实现的getBean
@Override
public T getBean(Class requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
再进入getBeanFactory()中观察
*/
@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
查看ConfigurableListableBeanFactory实现类为DefaultListableBeanFactory
<
至此再回到我们经常使用的ClassPathXmlApplicationContext中查看发现其包含的工作为,从xml中获取信息,之后再注入到DefaultListableBeanFactory容器中。注入调用refresh()
总结:AbstractApplicationContext的实现类,例如ClassPathXmlApplicationContext,负责获取xml配置文件信息,通过调用抽象类中refresh()方法将文件中的bean注入到DefaultListableBeanFactory容器中,DefaultListableBeanFactory实现BeanFactory中的所有方法,故得出结论spring的唯一容器为DefaultListableBeanFactory
Spring AOP
1)spring aop 前提知识
元注解、反射、静态代理、动态代理(jdk【接口代理】以及cglib【类代理】)
一、元注解
主要了解四个注解作用:
- @Target 标明注解可使用范围:METHOD【方法之上】TYPE【类之上】等等
- @Retention 表明注解作用范围(一般个人生命注解用RUNTIME即可)表示运行时使用
- @Document 文档注解了解即可
- @Inherited 表明注解可以被继承
二、反射
- jvm知识:每一个类、接口均在静态方法区中存储一份class,且属于唯一不重复
- 类加载有三种形式:c++类加载器 > 拓展类加载器 > 应用程序类加载器。我们一般使用的为应用程序类加载器,可通过this.getClass().getClassLoader()获取
- 获取到类Class对象之后便可获取类的信息,包含方法信息、属性信息、以及最重要通过反射获取对象实例的newInstance()
三、代理
关于代理的三种形式,读者可自行查询,在这里做简单说明。
- 静态代理:
实现同一个接口,实体对象需作为代理对象内部成员属性,代理对象通过代理实体对象属性方法实现代理操作。
缺点:不同接口需实现不同代理类,繁琐不利于代码管理。 - jdk动态代理:
实现interface InvocationHandler并实现方法public Object invoke(Object proxy, Method method, Object[] args),并通过Proxy类中的公共静态方法public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)获取代理对象。
原理:实现公共接口,
缺点:当类不存在接口时需更改原始代理,拓展性差。 - cglib动态代理:
解决不存在接口类实现代理。
原理:继承被代理类并重写方法
2)开启aop
spring 支持两种实现aop形式,注解、xml
2-1)注解实现aop
- 配置一个Config配置类,开启@EnableAspectJAutoProxy,注意该注解中的参数proxyTargetClass,当其为true代理使用cglib代理,相反则使用jdk代理。
- 生成一个自定义代理类并添加@Aspect
- 内部定义一个private方法并再添加@Pointcut(value = “execution(官方文档查阅)”)
- 定义切入方法,并注解@Before、@After、等
- 创建AnnotationConfigApplicationContext容器,并调用scan扫描包,获取被代理类对象,执行切入方法即可实现代理。
- ATTENTION(注意):若获取的为接口对象则可以用jdk代理,反之不可使用配置proxyTargetClass=true即可
2-2)xml实现aop
- 在resource目录中定义配置文件xml,并引入依赖aop标签
示例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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="customAdvice" class="com.tom.config.aspect.CustomAspect"/>
<bean id="userService" class="com.tom.service.impl.UserServiceImpl"/>
<aop:config proxy-target-class="true">
<aop:aspect ref="customAdvice">
<!-- <aop:pointcut id="servicePointcout" expression="execution(* com.tom.service.*.show(..))"/>-->
<!-- <aop:around method="around" pointcut-ref="servicePointcout"/>-->
<aop:around method="around" pointcut="execution(* com.tom.service.impl.UserServiceImpl.show())"/>
</aop:aspect>
</aop:config>
</beans>
- 参考官方文档吧,懒了 v__v
总结
还是看spring官方文档更确切。
Spring官方文档链接