spring ioc本质
spring的ioc实质就是程序员自己不创建对象,交给spring容器创建对象,创建了spring容器,就创建了容器中的对象,
使用时,调用getBean()即可。
spring ioc流程
1.读取pom文件
2.创建spring容器对象及bean对象设置
创建spring容器对象
appLocaltionContext ac = new ClassPathXmllocaltioncontext(applicationlContext.xml)
spring配置文件中 ,注册bean对象
applicaltion.xml文件,启动容器的同时,同时也创建了xml文件中的实例bean对象。
<bean id="stu" class="com.bjpowernode.pojo.Student">
**给属性赋值**
<property name="name" value="张三"></property>
<property name="age" value="21"></property>
</bean>
传入不同的参数,实例化对象
使用构造函数参数下标注入值
<bean id="stu" class="com.bjpowernode.pojo3.Student">
<constructor-arg index="0" value="钱七"></constructor-arg>
<constructor-arg index="2" ref="school"></constructor-arg>
<constructor-arg index="1" value="22"></constructor-arg>
</bean>
使用默认构造函数参数默认顺序注入值
<bean id="stuSequence" class="com.bjpowernode.pojo3.Student">
<constructor-arg value="陈十"></constructor-arg>
<constructor-arg value="22"></constructor-arg>
<constructor-arg ref="school"></constructor-arg>
</bean>
bean类java代码
交给Spring容器注入值,必须提供setXXX()方法和无参构造方法,实体类对象属性的修饰符是private
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
如要把对象交个spring容器管理,需要写明构造方法和set用于spring调用构造函数创建对象和给属性赋值。
3. 取出对象
student st = ac.getBean("stu")
ioc注解
就是不写spring配置文件中的bean,改为在代码中写注解 ,作用是一样的。
1.添加包扫描
<context:component-scan base-package=“com.bjpowernode.s01”></context:component-scan>
2.ioc注解 代码中
@Component("stu") //交给Spring去创建对象,就是在容器启动时创建
public class Student {
@Value("李四")
private String name;
@Value("23")
private int age;
//引用类型按类型注入
@Autowired
@Qualifier("schoolNew")
private School school;
@Component("schoolNew") //交给srping去创建对象
public class School { }
在三层架构中,各类注解
@controller 控制层
@service 业务逻辑
@repository 数据访问层
aop
就是一段逻辑都主逻辑和辅逻辑,而辅逻辑是个通用逻辑,在多个逻辑中多次出现,把主逻辑抽象为一个类,通常叫业务类,
辅助逻辑抽象为切面类,可以多次使用。创建代理时,业务类的实例对象作为目标对象,在增强功能过程中,调用切面类实例
对象的方法。
切面,非业务功能,就是增强的功能
连接点,目标方法
切入点,连接的集合,切入的位置
通知advice,切入的时机
目标对象,将要被增强的对象,操作谁,谁就是目标对象。
aspect
是对对aop的简易实现。
aspect是一个类 aop中使用了动态代理的形式,aspect是对目标对象方法的处理的一种简化方式,
aspect流程
A 、 Step1 :定义业务接口与实现类
public class SomeServiceImpl implements SomeService {
@Override
public void doSome(String name,Integer age) {
//给doSome方法增加一个功能,在doSome()执行之前, 输出方法的执行时间
System.out.println("====目标方法doSome()====");
}
B 、 Step2 :定义切面类
@Aspect
public class MyAspect {
@After(value = "mypt()")
public void myAfter(){
System.out.println("执行最终通知,总是会被执行的代码");
//一般做资源清除工作的。
}
C 、 Step3: : 声明目标对象切面类对象
//切入点 主逻辑
<bean id="someService" class="com.bjpowernode.ba08.SomeServiceImpl" />
<!--声明切面类对象-->
<bean id="myAspect" class="com.bjpowernode.ba08.MyAspect" />
D 、 Step4 :注册 AspectJ 的自动代理
<aop:aspectj-autoproxy ></aop:aspectj-autoproxy>
spring中使用mybatis
原理
就是将mybatis框架中的sqlsessionfactory对象交给spring来管理(spring配置文件中配置),
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定SqlSessionFactory对象的id-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.bjpowernode.dao"/>
</bean>
同时将dao层接口以属性的形式配置到spring中
<property name="basePackage" value="com.bjpowernode.dao"/>
再使用service层的实现类的实例对象调用dao层的接口实现类的对象中的方就可以对数据库进行操作。
spring中的mybatis
1.spring配置文件中配置mybatis及相关对象
<!--
把数据库的配置信息,写在一个独立的文件,编译修改数据库的配置内容
spring知道jdbc.properties文件的位置
-->
<context:property-placeholder location="classpath:jdbc.properties" />
<!--声明数据源DataSource, 作用是连接数据库的-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!--set注入给DruidDataSource提供连接数据库信息 -->
<!-- 使用属性配置文件中的数据,语法 ${key} -->
<property name="url" value="${jdbc.url}" /><!--setUrl()-->
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.passwd}" />
<property name="maxActive" value="${jdbc.max}" />
</bean>
<!--声明的是mybatis中提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionFactory的
SqlSessionFactory sqlSessionFactory = new ..
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--set注入,把数据库连接池付给了dataSource属性-->
<property name="dataSource" ref="myDataSource" />
<!--mybatis主配置文件的位置
configLocation属性是Resource类型,读取配置文件
它的赋值,使用value,指定文件的路径,使用classpath:表示文件的位置
-->
<property name="configLocation" value="classpath:mybatis.xml" />
</bean>
<!--创建dao对象,使用SqlSession的getMapper(StudentDao.class)
MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象。
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定SqlSessionFactory对象的id-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!--指定包名, 包名是dao接口所在的包名。
MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行
一次getMapper()方法,得到每个接口的dao对象。
创建好的dao对象放入到spring的容器中的。 dao对象的默认名称是 接口名首字母小写
-->
<property name="basePackage" value="com.bjpowernode.dao"/>
</bean>
<!--声明service-->
<bean id="studentService" class="com.bjpowernode.service.impl.StudentServiceImpl">
<property name="studentDao" ref="studentDao" />
</bean>
2.调用
String config="applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
//获取spring容器中的dao对象
StudentDao dao = (StudentDao) ctx.getBean("studentDao");
与spring正常使用一样,现在spring配置文件中配置bean,然后调用
数据库事务隔离级别
多个事务同时运行时,可读写的情况。
未提交读 脏读
提交读 不重复读 oracle
重复读 读一次后,再次读取的数据都一样 mysql
串行读 一个事务执行完之后,下一个事务才可以读写
spring中使用mybatis事务
java事务是把数据库中的事务提到了业务层。
spring对mybatis事务进行管理2种方式 1.注解 2.aspect
1.基于注解的事务添加步骤
- 在applicationContext_service.xml文件中添加事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--因为事务必须关联数据库处理,所以要配置数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
- 在applicationContext_service.xml文件中添加事务的注解驱动
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
- 业务层 public 方法添加业务属性
如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理
public class BuyGoodsServiceImpl implements BuyGoodsService {
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.DEFAULT,
readOnly = false,
rollbackFor = {
NullPointerException.class, NotEnoughException.class
}
@Override
public void buy(Integer goodsId, Integer nums) {}
传播性 PROPAGATION
就是一个事务的操作环境,与其他事务之间的关系,是否可以在另一个事务中等,
@Service //交给Spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {
**事务配置就是给把dao层的事务逻辑提前放到了service层,给service类中的方法添加事务属性,如隔离级别,传播性等,此时service中的方法就是主逻辑,事务属性就是辅助逻辑,也可说是增强功能。然后绑定切面和切入点,此时就用到了aop原理。
**
使用 AspectJ 的 AOP 配置管理事务
1. 添加事务管理器
<!--添加事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
2. 配置事务切面
<!--配置事务切面-->
<tx:advice id="myadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*select*" read-only="true"/>
<tx:method name="*find*" read-only="true"/>
<tx:method name="*search*" read-only="true"/>
<tx:method name="*get*" read-only="true"/>
<tx:method name="*insert*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="*add*" propagation="REQUIRED"/>
<tx:method name="*save*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
<tx:method name="*set*" propagation="REQUIRED"/>
<tx:method name="*update*" propagation="REQUIRED"/>
<tx:method name="*change*" propagation="REQUIRED"/>
<tx:method name="*modify*" propagation="REQUIRED"/>
<tx:method name="*delete*" propagation="REQUIRED"/>
<tx:method name="*remove*" propagation="REQUIRED"/>
<tx:method name="*drop*" propagation="REQUIRED"/>
<tx:method name="*clear*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
3. 绑定切面和切入点
<!--绑定切面和切入点-->
<aop:config>
<aop:pointcut id="mycut" expression="execution(* com.bjpowernode.service.impl.*.*(..))"></aop:pointcut>
<aop:advisor advice-ref="myadvice" pointcut-ref="mycut"></aop:advisor>
</aop:config>
就可以使用了