ioc

ioc,控制反转。 底层 xml解析 反射 工厂模式

spring的自动注入方式 1、通过set方式 2、通过有参构造器注入

spring通过加载xml,获取bean类路径,然后通过反射生成对象,再根据xml配置的值通过set方法注入值。

注入的两种方式xml配置格式

  1. #set注入 property标签
  2. <bean id="user" class="com.bean.user" scope="singleton">
  3. <property name="name" value="111"/>
  4. <property name="id" value="1"/>
  5. <property name="sex" value="0"/>
  6. </bean>
  7. #有参构造器注入 constructor-arg标签
  8. <bean id="user1" class="com.bean.user">
  9. <constructor-arg name="name" value="xxx"/>
  10. </bean>
  11. # 注入对象
  12. <bean id="user" class="com.bean.user" scope="singleton">
  13. <property name="name" value="111"/>
  14. <property name="id" value="1"/>
  15. <property name="sex" value="0"/>
  16. <property name="obj" ref="xx_id"/> //这个id是xml配置中其他bean的id
  17. </bean>
  18. #也可以只写内部

注入不同类型

  1. #数组
  2. <property name="name">
  3. <array>
  4. <value>123</value>
  5. </array>
  6. </property>
  7. #List
  8. <property name="name">
  9. <list>
  10. <value>123</value>
  11. <ref bean="xxx_id"></ref> //这个id是xml配置中其他bean的id,配置集合中存类对象
  12. </list>
  13. </property>
  14. #Map
  15. <property name="name">
  16. <map>
  17. <entry key="key" value="value"/>
  18. </map>
  19. </property>
  20. #set
  21. <property name="name">
  22. <set>
  23. <value>11321</value>
  24. </set>
  25. </property>

bean的作用域

scope singleton 单实例 prototype 多实例

bean的生命周期

  • 确定构造方法
  • 实例化
  • 填充属性,也就是依赖注入
  • 处理Aware回调
  • 初始化前,执行BeanPostProcessor的postProcessBeforeInitialization()方法
  • 初始化,处理InitializingBean接⼝
  • 初始化后,执行BeanPostProcessor的postProcessAfterInitialization()方法
  • 销毁对象时,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
  • 如果配置了destory-method属性,则执行对应的方法。

    AOP

    使用技术: 动态代理:

    • 有接口的情况,使用JDK的动态代理
    • 没有接口,使用CGLIB的代理

代理

Proxy.newProxyInstance(当前类加载器,代理接口数组,InvocationHandler增强器子类) 通过newProxyInstance返回代理对象,再由代理对象调用接口的方法

  1. public static void main(String[] args) {
  2. Class[] interfaces = {Userdao.class};//接口
  3. UserD userD = new UserD();//接口实现类
  4. //获取代理对象
  5. Userdao o =(Userdao) Proxy.newProxyInstance(MyProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userD));
  6. o.add(1,2); //代理对象执行方法
  7. }

增强器,实现InvocationHandler

  1. class UserDaoProxy implements InvocationHandler{
  2. private Object object;
  3. public UserDaoProxy(Object o){
  4. this.object = o;
  5. }
  6. @Override
  7. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  8. System.out.println(args);
  9. Object invoke = method.invoke(object, args);
  10. return invoke;
  11. }
  12. }

基于xml配置

  1. 第一步:配置通知类
  2. 第二步:使用aop:config标签开始配置aop
  3. 第三步:使用aop:aspect标签表明配置切面
  4. id:给切面提供一个唯一标识
  5. ref:指定通知类bean的id
  6. 第四步:在aop:aspect内部使用对应的标签来配置通知类型
  7. 在切入点方法执行之前执行,所以是前置通知
  8. aop:before method用来指定类中的哪一个方法是前置通知
  9. 切入点表达式:execution(表达式)
  10. 修饰符 返回值 包名。。。类名。方法名(参数)
  11. 例子:public void com.service.accountservice.saveAccount()
  12. 四种常用通知类型
  13. aop:before 前置通知
  14. aop:after-returning 后置通知
  15. aop:after-throwing 异常通知
  16. aop:after 最终通知
  17. 通用切入点配置
  18. 标签:aop:pointcut id="标识" expression="切入点表达式"
  19. 写在aop:aspect 只有当前切面可以用,写在上边所有前面可用
  20. aop:around 环绕通知
  21. <aop:config proxy-target-class="true">
  22. <aop:aspect id="log" ref="Logger">
  23. <aop:before method="printlog"
  24. pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:before>
  25. <aop:after-returning method="after_e"
  26. pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:after-returning>
  27. <aop:after-throwing method="after_t"
  28. pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:after-throwing>
  29. <aop:after method="after"
  30. pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:after>
  31. <aop:around method="around" pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:around>
  32. </aop:aspect>
  33. </aop:config>
  34. <aop:config>
  35. <aop:pointcut id="log" expression="execution(public void com.service.accountservice.saveAccount())"/>
  36. <aop:advisor advice-ref="l" pointcut-ref="log"/>
  37. </aop:config>

基于注解配置aop

配置切面如下:
除此之外,还要设置@EnableAspectJAutoProxy
在xml中配置proxy-target-class=”false”,默认就是false

  1. @Component
  2. @Aspect
  3. public class LogAdvice {
  4. @Pointcut("execution(* com.ssm.service.*Impl.*(..))")
  5. public void pointcut(){}
  6. @Before("pointcut()")
  7. public void before(){
  8. System.out.println("前置通知");
  9. }
  10. @AfterReturning("pointcut()")
  11. public void afterReturn(){
  12. System.out.println("返回通知");
  13. }
  14. public void afterThrow(){
  15. System.out.println("异常通知");
  16. }
  17. @After("pointcut()")
  18. public void after(){
  19. System.out.println("后置通知");
  20. }
  21. }

spring启动的过程,会扫描xml或者配置文件,对pointcut包含的类生成代理对象。使用自动注入bean的时候,注入的是代理对象,代理对象中包含了配置的通知信息。

事务

spring事务传播有7中