spring 自动注入
Posted 苦逼的人生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring 自动注入相关的知识,希望对你有一定的参考价值。
1.IOC和DI
IOC侧重的是思想 ,DI实现
IOC侧重构造对象:通过容器 DI对属性值进行注入 (普通属性和域属性的注入)
2.aop
第一个案例
1.增强:前置和后置
MethodBeforeAdvice AfterReturningAdvice 接口
before() afterRetruing()
2.增强也需要再xml中进行配置
3.AOP操作在配置文件中
<!--dao层的配置-->
<bean id="someDAO" class="cn.happy.day03aop.dao.SomeDAOImpl"></bean>
<!--service层的配置-->
<bean id="someService" class="cn.happy.day03aop.service.SomeServiceImpl">
<property name="dao" ref="someDAO"></property>
</bean>
<!--增强:通知Advice-->
<bean id="beforeAdvice" class="cn.happy.day03aop.aop.MyBeforeAdvice"></bean>
切面
<aop:config>
<aop:pointcut id="mypointcut" expression="execution(public void doSome())">
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="mypointcut">
</aop:advisor>
</aop:config>
3.切点表达式
* *..UserServiceImpl.*(..)
void 全名称 cn.cn.cn.cn.cn.UserServiceImpl.*(..)
String
int
4.方法签名
切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显就是方法的签名。
注意:表达式中加[]的部分表示可省略部分,各部分间用空格分开。在其中可以使用以下符号:
符号 意义
* 0至多个任意字符
.. 用在方法参数中,表示任意多个参数
用在包名后,表示当前包及其子包路径
+ 用在类名后,表示当前类及其子类
用在接口后,表示当前接口及其实现类
案例:
execution(public * *(..)) 指定切入点为:任意公共方法
execution(* set*(..)) 指定切入点为:任何一个以"set"开始的方法
5. 注入方式
1.设值注入
2.构造注入
条件1:带参构造 无参构造
条件2:
<bean id="stu">
<constructor-arg index="0" value="张三">
</bean>
3.p命名空间注入
1.copy一个p
2.<bean id="stu" p:name="张三" p:car-ref="car">
4.集合属性注入
array set list map properties k=v
4.BeanFactory 延迟咱们bean初始化 ,使用的时候再做初始化和ApplicationConext.
ApplicationConext 是BeanFactory的孙子接口
ApplicationConext 容器创建,bean就做初始化
5.Servlet的初始化时机
解析:看情况:1.看xml中 load-on-startup 0或者正整数 容器启动,bean已经初始化
2.没有的话或者为负数,用户第一次访问Servlet
6.Spring中Bean作用域 scope="singleton/prototype"
7.域属性自动注入
byName:要求:配置文件中可以有多个对象,但是默认只自动装配和属性同名的bean的id对象
byType:要求:相容类型的对象只能有一个
7个专业术语
增强处理/通知(Advice)
增强类中的方法
切入点(Pointcut)
符合切点表达式的方法才能称为切入点
连接点(Join Point)
目标对象中的所有方法都是连接点
切面(Aspect)
增强类
目标对象(Target object)
等待被增强的对象
AOP代理(AOP proxy)
代理对象,内存中创建的。
织入(Weaving)
将切面和目标对象进行绑定的过程
注解的DI
1.什么是注解
有人说:@Override 在Java中,有小鼠标的就是注解
2.注解的用法
@Override 标识子类中的方法一定来源于父类
@Test 单测方法
@After 在单测后执行
@Before 前执行
@WebServlet(name="" urlpatterns="{"/"}") 对外公开访问地址
@SuppressWarnings() 取消警告
3.注解主要含义
解析:注解的本质是接口
自定义注解
4.注解的方法
解析:注解是给谁看的,Java编译器 Java编译器会获取到注解的类型元数据。对该类或者方法进行特殊的照顾处理
5.基于注解DI(有*和无*)
component-scan 组件扫描
base-package="cn.happy.day07annotationdi" 扫描本身和子包
base-package="cn.happy.day07annotationdi.*" 只扫描子包
@Component 标识一个类是被Spring容器管理的一个bean
分层的情况
@Repository dao
@Service service
@Controller 控制层
@Value 给类的普通属性赋值
@Resource 给类的域属性赋值
@AutoWired 给类的域属性赋值
金牌结论:如果直接在域属性上写Resource。没有指定名称,先按照byName尝试装配,如果容器中
,没有和成员变量同名的bean,那么继续使用byType进行装配。如果byType
检测到相容的类型有多个,就报错:expected single matching,but found 2;
代理
两类:动态代理和静态代理
静态代理:代理模式
代理:
1.代理
招生的速度加快了
2.代理
房屋中介
3.对原有对象的行为进行增强
抽象主题:Subject:接口
目标对象(原始对象):RealSubject(要增强的对象) implements
代理对象:Proxy(植入目标对象) 实现了接口
before code block
business xxx.invoke()
after code block
动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理
1)JDK 在运行时运行时注入
本质:在内存中构建出接口的实现类
特点:被代理对象,必须有接口
Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
InvocationHandler调度处理器
public interface InvocationHandler {
}
ClassLoader loader, 类加载器(孙卫琴) 如何获取到类加载器?
Class<?>[] interfaces,
InvocationHandler h 调度处理器
CGLIB动态代理: 编译的时候
特点:再一个类型没有接口的情况下进行代理
实质:内存中构建了出了目标类型的子类
对于不使用接口的业务类,无法使用JDK动态代理,cglib采用非常底层的字节码技术,
可以为一个类创建子类
CGLIB动态代理 无接口代理 编译已经增强
final SomeServiceImpl service=new SomeServiceImpl();
Enhancer enhancer=new Enhancer();
enhancer.setSuperClass(service.getClass());
enhancer.setCallBack(new MethodInterceptor(){
public Object intercept(Object o,Method method,Object[] objects,MethodProxy methodProxy){
sout("before=========");
Object resullt=methodProxy.invoke(service,objects);
return result;
}
});
SomeServiceImpl proxy=(SomeServiceImpl)enhancer.create();
proxy.doSome();
以上是关于spring 自动注入的主要内容,如果未能解决你的问题,请参考以下文章
spring的两种属性注入方式setter注入和构造器注入或者自动注入
Spring5依赖注入常用的三种方法:构造注入Setter注入自动装配
Spring 3.0 学习-DI 依赖注入_创建Spring 配置-使用一个或多个XML 文件作为配置文件,使用自动注入(byName),在代码中使用注解代替自动注入,使用自动扫描代替xml中bea(