IOC
DI 依赖注入
在bean中指定对应的依赖。 需要提供依赖对象对应的setter方法(容器去执行)
<bean id="bookservice" class="service">
<property name="bookDao" ref="bookDao"/>
</bean>
bean的配置
- -基础配置 id class
- 别名 name="xxx"
- 作用范围 scope="" 默认为单例
spring实例化bean
方法一 调用bean的无参构造函数。(常用)
一般报错看倒数1,2行的报错。
方法二 使用静态工厂实例化bean
方法三 实例工厂(工厂不是静态)
![3DKNJFBLUDH~UPG]}I76@WE.png](p9-juejin.byteimg.com/tos-cn-i-k3…?)
方法四 使用FactoryBean实例化bean 使用getObject()创建对象
bean的生命周期
init-method="init" 初始化所有的函数 destory-method="destory" 销毁所用的函数
setter依赖注入
1 引用类型
2 简单类型
构造器注入(constructor-arg)
偶合度较高
1 引用类型
2 简单类型
解决参数名称耦合问题
依赖自动装配(只能对引用类型作用)
按类型
自动寻找set所需要的类型 按类型装配其实不需要id
按名称
根据set函数的名称,来确定 setBookDao截取后的到bookDao为名字
集合注入
数组 list set map Properties
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<!--数组注入-->
<property name="array">
<array>
<value>100</value> //简单类型用value
<value>200</value>
<ref bean="beanId"/> //引用类型用ref
</array>
</property>
<!--list集合注入-->
<property name="list">
<list>
<value>itcast</value>
<value>itheima</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>itcast</value>
<value>itheima</value>
</set>
</property>
<!--map集合注入-->
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
</map>
</property>
<!--Properties注入-->
<property name="properties">
<props>
<prop key="country">china</prop>
</props>
</property>
</bean>
加载properties文件
创建新的命名空间
1 开启context命名空间
2 使用context空间加载properties文件
3 使用属性占位符${}读取properties文件中的属性
加载多个配置文件
<context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER>
所有的properties文件都加载
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER>
容器
BeanFactory创建完毕后 所有bean均延迟加载
总结
容器
bean
依赖注入(向bean中注入数据)
注解开发
<bean id="bookservice" class="service" init-method="init" destory-method="destory">
简化为下图
如果Component后不写内容则需要使用类型访问
base-package 扫描这个目录下的所有文件
规范化名称
纯注解开发模式(spring3.0不应该有配置文件了)
目标:使用 代替配置文件
初始化容器也发生了变化
注解开法控制bean作用范围与生命周期
控制是否为单例 默认为单例 @Scope("prototype") 设置为非单例 生命周期 @PostConstruct构造方法后 @PerDestroy 彻底结束前
依赖注入
自动装配 @Autowired
引用类型
默认为按类型装配
想要按名称装配 想要在Component注解后加入名字 如Repository("bookDao1")
简单类型
@Value("100")
private String name;
使用配置文件注入简单类型
配置类
@Configuration
@ComponentScan("com.itheima")
//@PropertySource加载properties配置文件
@PropertySource({"jdbc.properties"})
public class SpringConfig {
}
要注入的类
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
//@Value:注入简单类型(无需提供set方法)
@Value("${name}")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
管理第三方bean
@bean
但是都写在这里会导致SpringConfig太乱
使用导入方式管理bean
为第三方bean 注入资源
简单类型
引用类型
引用类型只需要给个形参 就会自动装配
@Bean
public DataSource dataSource(BookDao bookDao){
System.out.println(bookDao);
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
Spring整合MyBatis
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
AOP简介 面向切面编程 (一种编程范式)
作用:在不惊动原始设计的基础上为其进行功能增强(不该源代码的情况下追加功能)
spring理念:无入侵编程
AOP入门案例
1 导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
2 制作连接方法,切面类 注意:切入点定义依托与一个不具有实际意义的方法进行,既无参数,无返回值,方法体无实际逻辑
//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
//设置切入点,要求配置在方法上方
@Pointcut("execution(void com.itheima.dao.BookDao.update())")
private void pt(){}
//设置在切入点pt()的前面运行当前操作(前置通知)
@Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
}
3 在配置类中开启注解的aop编程
@Configuration
@ComponentScan("com.itheima")
//开启注解开发AOP功能
@EnableAspectJAutoProxy
public class SpringConfig {
}
AOP工作流程
切入点表达式(控制给谁加)
@Pointcut("execution(....................)")
AOP通知类型(控制往哪里加)
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(void com.itheima.dao.BookDao.update())")
private void pt(){}
@Pointcut("execution(int com.itheima.dao.BookDao.select())")
private void pt2(){}
//@Before:前置通知,在原始方法运行之前执行
// @Before("pt()")
public void before() {
System.out.println("before advice ...");
}
//@After:后置通知,在原始方法运行之后执行
// @After("pt2()")
public void after() {
System.out.println("after advice ...");
}
//@Around:环绕通知,在原始方法运行的前后执行
// @Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before advice ...");
//表示对原始操作的调用
Object ret = pjp.proceed();
System.out.println("around after advice ...");
return ret;
}
// @Around("pt2()")
public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before advice ...");
//表示对原始操作的调用
Integer ret = (Integer) pjp.proceed();
System.out.println("around after advice ...");
return ret;
}
//@AfterReturning:返回后通知,在原始方法执行完毕后运行,且原始方法执行过程中未出现异常现象
// @AfterReturning("pt2()")
public void afterReturning() {
System.out.println("afterReturning advice ...");
}
//@AfterThrowing:抛出异常后通知,在原始方法执行过程中出现异常后运行
@AfterThrowing("pt2()")
public void afterThrowing() {
System.out.println("afterThrowing advice ...");
}
}
ProceedingJoinPoint类的方法
//获取执行的签名对象
Signature signature = pjp.getSignature();
//类型
String className = signature.getDeclaringTypeName();
//方法名
String methodName = signature.getName();
AOP通知获取数据
- 获取参数
- 获取返回值
- 获取异常
获取参数
JoinPoint jp (如果通知方法参数中有他,则他必须在第一个位置)
jp.getArgs()
ProceedingJoinPoint pjp
pjp.getArgs()
作用:可以对参数进行处理
获取返回值
获取异常
spring事物
在数据层或者业务层保证一系列的数据库操作同成功同失败
1 一般@Transactional写在接口上不写在实现类上 写在AccountService上
2 创建事物管理器
3 在配置文件中声明事物
Spring事物角色(spring如何实现事物)
将多个事物合并在一起,合并为一个到时候一起提交
管理员:transfer 协调员:outMoney
Spring事物属性
事物回滚
并不是所有异常都会使事物回滚 根据rollbackFor设置