1.IOC(二)
1.1基于注解的属性赋值
-
@Value:给基本类型的属性赋值的
-
@Autowired:给引用类型的属性赋值,是spring自带的,原理和@Resource注解
-
@Resource: 给引用类型的属性赋值,是JDK自带的
@Autowired(同 @Resource)注解原理: 首先会根据当前属性的类型去容器中找该类型的唯一bean对象: 第一种:容器没有该类型的对象:报错 第二种: 容器中有该类型的唯一bean对象,就将该唯一bean对象赋值给该属性 第三种:容器中有多个【两个及以上】该类型的唯一bean对象,它会再根据该属性 名去容器中找,看看容器中的哪个bean对象的id值和该属性名一致,如果有,就将容器中该对象赋值给该属性,如果没有报错。
1.2引用类型属性的装配
引用类型的属性装配:
- 手动装配:构造器、set方法(property标签、p名称空间)
- 自动装配:
基于xml配置:
基于注解的: @Resource/@Autowired注解
基于xml的属性的自动装配
<bean id="dog1" class="com.offcn.p1.bean.Dog">
<property name="did" value="123"/>
<property name="name" value="藏獒"/>
</bean>
<bean id="dog" class="com.offcn.p1.bean.Dog">
<property name="did" value="124"/>
<property name="name" value="狗狗"/>
</bean>
<bean class="com.offcn.p1.bean.Person" autowire="byName">
<property name="pid" value="90"></property>
<property name="name" value="老师"></property>
</bean>
1.3加载properties配置文件
配置文件中的配置:
<!-- 加载properties配置文件信息,location属性指定properties配置文件的路径及名称 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:component-scan base-package="com.offcn.p2"/>
<!-- 配置数据源信息 -->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.userName}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean>
2.Spring的Aop
2.1Spring的Aop简介[面试题]
AOP:全称Aspect Oriented Programming:面向切面编程
OOP:全称Object Oriented Programming:面向对象编程
Aop和OOP不是谁取代谁的问题,是相互促进,相互补充的关系。
Aop是在不改变原有OOP类代码的基础之上,对原来类的功能【方法】进行拓展。
Aop理解:
- 定义:Aop全称Aspect Oriented Programming面向切面编程,它是在不改变原来类代码的基础之上,对原有类的功能进行拓展。
- 解决了:解决了软件工程中提出的关注点分离的问题,让不同的部分处理不同的问题。
- 底层实现: 动态代理【JDK动态代理+CGLIB代理】
2.2提出问题:
实现一个计算器,计算器有加减乘除功能。加减乘除之前或者之后增加输出日志的功能。
实现:
-
基本实现:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200226200111893.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0MDA5Nw==,size_16,color_FFFFFF,t_70 -
AOP: 在不变原有类代码基础上对业务逻辑功能拓展。
2.3Aop中涉及到几个概念
通知【Advice】:拓展的功能【添加日志】,称为:通知【本质:方法】
切面【Aspect】:通知所在的类,称为:切面【本质:类】
切入点【PointCut】:指定对哪个类的哪些方法拓展,【本质:表达式】
连接点【JoinPoint】:通知和目标方法的交点称为连接点
目标对象【Target】:被拓展的类对象,称为:目标对象
织入【Weaving】:将通知应用到目标方法的过程,称之为:织入
2.4代理的概念
代理:代理就是由代理人代替被代理人完成某件事。代理的作用:简化被代理人完成某件事的手续。
用户【被代理人】和支付宝【代理】
Java中也有代理概念:Java中的代理有静态代理、动态代理
- 静态代理:要求被代理类和代理类都实现同一个接口,接口是唯一的。
- 动态代理:
JDK动态代理:要求被代理类和代理类实现相同接口,但是接口不唯一 。
CGLIB代理:不要求被代理类实现接口。
2.5Aop对于问题实现
第一步:导入jar包
第二步:将被代理类和切面类放入到容器中。
第三步:在切面类上加@Aspect注解,开启基于注解的aop支持
第四步:在切面类中写通知【方法】
接口:
public interface Caculator {
public int add(int i,int j);
public int substract(int i,int j);
public int multiply(int i,int j);
public int divide(int i,int j);
}
实现类:
@Component
public class CaculatorImpl implements Caculator {
@Override
public int add(int i, int j) {
int result = i +j;
System.out.println("add method.............");
return result;
}
@Override
public int substract(int i, int j) {
int result = i - j;
return result;
}
@Override
public int multiply(int i, int j) {
int result = i * j;
return result;
}
@Override
public int divide(int i, int j) {
int result = i / j;
return result;
}
}
切面类:
@Component
@Aspect//这表示当前类是一个切面类
public class LogAspect {
@Before("execution(public int com.offcn.p1.service.CaculatorImpl.add(int, int))")
public void printBeforeLog() {
System.out.println("method before.........");
}
@After("execution(public int com.offcn.p1.service.CaculatorImpl.add(int, int))")
public void printAfterLog() {
System.out.println("method after.........");
}
}
Spring配置文件:
<context:component-scan base-package="com.offcn.p1"/>
<!-- 开启基于注解的切面支持 -->
<aop:aspectj-autoproxy/>