ioc
ioc,控制反转。 底层 xml解析 反射 工厂模式
spring的自动注入方式 1、通过set方式 2、通过有参构造器注入
spring通过加载xml,获取bean类路径,然后通过反射生成对象,再根据xml配置的值通过set方法注入值。
注入的两种方式xml配置格式
#set注入 property标签<bean id="user" class="com.bean.user" scope="singleton"><property name="name" value="111"/><property name="id" value="1"/><property name="sex" value="0"/></bean>#有参构造器注入 constructor-arg标签<bean id="user1" class="com.bean.user"><constructor-arg name="name" value="xxx"/></bean># 注入对象<bean id="user" class="com.bean.user" scope="singleton"><property name="name" value="111"/><property name="id" value="1"/><property name="sex" value="0"/><property name="obj" ref="xx_id"/> //这个id是xml配置中其他bean的id</bean>#也可以只写内部
注入不同类型
#数组<property name="name"><array><value>123</value></array></property>#List<property name="name"><list><value>123</value><ref bean="xxx_id"></ref> //这个id是xml配置中其他bean的id,配置集合中存类对象</list></property>#Map<property name="name"><map><entry key="key" value="value"/></map></property>#set<property name="name"><set><value>11321</value></set></property>
bean的作用域
scope singleton 单实例 prototype 多实例
bean的生命周期
- 确定构造方法
- 实例化
- 填充属性,也就是依赖注入
- 处理Aware回调
- 初始化前,执行BeanPostProcessor的postProcessBeforeInitialization()方法
- 初始化,处理InitializingBean接⼝
- 初始化后,执行BeanPostProcessor的postProcessAfterInitialization()方法
- 销毁对象时,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
- 如果配置了destory-method属性,则执行对应的方法。
AOP
使用技术: 动态代理:
- 有接口的情况,使用JDK的动态代理
- 没有接口,使用CGLIB的代理
代理
Proxy.newProxyInstance(当前类加载器,代理接口数组,InvocationHandler增强器子类) 通过newProxyInstance返回代理对象,再由代理对象调用接口的方法
public static void main(String[] args) {Class[] interfaces = {Userdao.class};//接口UserD userD = new UserD();//接口实现类//获取代理对象Userdao o =(Userdao) Proxy.newProxyInstance(MyProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userD));o.add(1,2); //代理对象执行方法}
增强器,实现InvocationHandler
class UserDaoProxy implements InvocationHandler{private Object object;public UserDaoProxy(Object o){this.object = o;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(args);Object invoke = method.invoke(object, args);return invoke;}}
基于xml配置
第一步:配置通知类第二步:使用aop:config标签开始配置aop第三步:使用aop:aspect标签表明配置切面id:给切面提供一个唯一标识ref:指定通知类bean的id第四步:在aop:aspect内部使用对应的标签来配置通知类型在切入点方法执行之前执行,所以是前置通知aop:before method用来指定类中的哪一个方法是前置通知切入点表达式:execution(表达式)修饰符 返回值 包名。。。类名。方法名(参数)例子:public void com.service.accountservice.saveAccount()四种常用通知类型aop:before 前置通知aop:after-returning 后置通知aop:after-throwing 异常通知aop:after 最终通知通用切入点配置标签:aop:pointcut id="标识" expression="切入点表达式"写在aop:aspect 只有当前切面可以用,写在上边所有前面可用aop:around 环绕通知<aop:config proxy-target-class="true"><aop:aspect id="log" ref="Logger"><aop:before method="printlog"pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:before><aop:after-returning method="after_e"pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:after-returning><aop:after-throwing method="after_t"pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:after-throwing><aop:after method="after"pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:after><aop:around method="around" pointcut="execution(public void com.service.accountservice.saveAccount())"></aop:around></aop:aspect></aop:config><aop:config><aop:pointcut id="log" expression="execution(public void com.service.accountservice.saveAccount())"/><aop:advisor advice-ref="l" pointcut-ref="log"/></aop:config>
基于注解配置aop
配置切面如下:
除此之外,还要设置@EnableAspectJAutoProxy
在xml中配置proxy-target-class=”false”,默认就是false
@Component@Aspectpublic class LogAdvice {@Pointcut("execution(* com.ssm.service.*Impl.*(..))")public void pointcut(){}@Before("pointcut()")public void before(){System.out.println("前置通知");}@AfterReturning("pointcut()")public void afterReturn(){System.out.println("返回通知");}public void afterThrow(){System.out.println("异常通知");}@After("pointcut()")public void after(){System.out.println("后置通知");}}
spring启动的过程,会扫描xml或者配置文件,对pointcut包含的类生成代理对象。使用自动注入bean的时候,注入的是代理对象,代理对象中包含了配置的通知信息。
事务
spring事务传播有7中
