-
Spring概述:
-
Spring体系结构
-
-
IOC的概念和作用
-
耦合指的是对象之间的依赖关系,耦合越小越好
-
以jdbc为例
- 通过反射来注册驱动,那么会造成驱动名称写死在程序当中,这种结果显然是不太合理的
- 通过配置文件的形式可以解决这种耦合问题
-
控制反转模式
- 之前程序之间获取对象是通过new的方式
- 现在由框架主动线程生成对象,程序被动接受框架生成的对象
-
IOC作用就是削减计算程序之间的耦合关系
-
BeanFactory and ApplicationContext的区别
-
BeanFactory才是Spring容器的顶层接口,Application是BeanFactory的子接口
-
ApplicationContext只要读取配置文件,默认情况下就会创建对象
-
BeanFactory 什么时候使用,什么时候在创建对象
-
ApplicationContext接口的实现类:
- ClassPathXmlApplicationContext:是从类的根路径下加载配置文件
- FileSystemXmlApplicationContext:是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
- AnnotationConfigApplicationContext:当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解
-
-
IOC中的bean标签和管理对象细节
-
bean标签:配置对象给Spring来创建,默认情况下调用的是无参构造函数,如没有无参构造函数则不能创建成功
-
实例化对象Bean的三种方式
- 使用默认的午餐构造函数:
- spring 管理静态工厂-使用静态工厂的方法创建对象
- spring 管理实例工厂-使用实例工厂的方法创建对象
-
依赖注入
-
实现持久层对象传入业务层
-
构造函数注入
<!--构造函数注入: 使用的标签:constructor-arg 标签出现的位置:bean标签的内部 标签中的属性 type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型 index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始 name:用于指定给构造函数中指定名称的参数赋值 常用的 =============以上三个用于指定给构造函数中哪个参数赋值=============================== value:用于提供基本类型和String类型的数据 ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 优势: 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。 弊端: 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。 --> <bean id="accountService" class="com.SpringDemo4springDI.service.IAccountServiceImpl"> <constructor-arg name="name" value="泰斯特"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" ref="now"></constructor-arg> </bean>
-
set方法注入
<!-- set方法注入 更常用的方式 涉及的标签:property 出现的位置:bean标签的内部 标签的属性 name:用于指定注入时所调用的set方法名称 value:用于提供基本类型和String类型的数据 ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 优势: 创建对象时没有明确的限制,可以直接使用默认构造函数 弊端: 如果有某个成员必须有值,则获取对象是有可能set方法没有执行。 --> <!-- 配置一个日期对象 --> <bean id="now" class="java.util.Date"></bean> <bean id="accountService2" class="com.SpringDemo4springDI.service.IAccountServiceImp2"> <property name="name" value="TEST" ></property> <property name="age" value="21"></property> <property name="birthday" ref="now"></property> </bean>
-
集合注入
<!-- 复杂类型的注入/集合类型的注入 用于给List结构集合注入的标签: list array set 用于个Map结构集合注入的标签: map props 结构相同,标签可以互换 --> <bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3"> <property name="myStrs"> <set> <value>AAA</value> <value>BBB</value> <value>CCC</value> </set> </property> <property name="myList"> <array> <value>AAA</value> <value>BBB</value> <value>CCC</value> </array> </property> <property name="mySet"> <list> <value>AAA</value> <value>BBB</value> <value>CCC</value> </list> </property> <property name="myMap"> <props> <prop key="testC">ccc</prop> <prop key="testD">ddd</prop> </props> </property> <property name="myProps"> <map> <entry key="testA" value="aaa"></entry> <entry key="testB"> <value>BBB</value> </entry> </map> </property> </bean>
-
-
基于注解实现
-
Component:用于把当前类对象存入到Spring容器当中
-
Controller:表现层
-
@Service 业务层
- @Autowired 自动类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功;
- @Qualifier 用于指定注入bean的id;
- @Resource 可独立使用 类似Autowired
-
@Repository 持久层
-
-
基于注解的IOC配置
-
注解解决容易问题
在测试类中,每个测试方法都有以下两行代码: ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); IAccountService as = ac.getBean("accountService",IAccountService.class); 这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。 解决方案: 依靠 spring 框架,因为它提供了一个运行器,可以读取配置文件(或注解)来创建容器。我 们只需要告诉它配置文件在哪就行 /** * 使用Junit单元测试:测试我们的配置 * Spring整合junit的配置 * 1、导入spring整合junit的jar(坐标) * 2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的 * @Runwith * 3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置 * @ContextConfiguration * locations:指定xml文件的位置,加上classpath关键字,表示在类路径下 * classes:指定注解类所在地位置 * * 当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上 @RunWith 注解替换原有的运行器 @ContextConfiguration 指定Spring配置文件的位置 @AutoWired给测试类中的变量注入数据 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfiguration.class) public class AccountServiceTst { @Autowired private IAccountService accountService; @Test public void testFindAll(){ List<Account> accounts = accountService.findAllAccount(); for (Account account : accounts) { System.out.println(account); } } }
-
-
-
-
AOP的相关概念:
-
AOP 面向切面编程
-
使用动态代理技术实现代码运行期间,不修改源码对已有方法进行增强的操作
private IAccountDao accountDao = new AccountDaoImpl(); @Override public void saveAccount(Account account) { try { TransactionManager.beginTransaction(); accountDao.save(account); TransactionManager.commit(); } catch (Exception e) { TransactionManager.rollback(); e.printStackTrace(); }finally { TransactionManager.release(); } } @Override public void updateAccount(Account account) { try { TransactionManager.beginTransaction(); accountDao.update(account); TransactionManager.commit(); } catch (Exception e) { TransactionManager.rollback(); e.printStackTrace(); }finally { TransactionManager.release(); } } // 以上有很多重复的事务代码,需要进一步优化处理 // 解决方案: 使用动态代理技术解决重复代码问题
public class BeanFactory { // 创建代理对象工厂 private IAccountService accountService; private TransactionManager transactionManager; public final void setAccountService(IAccountService accountService) { this.accountService = accountService; } public void setTransactionManager(TransactionManager transactionManager) { this.transactionManager = transactionManager; } public IAccountService getAccountService(){ return (IAccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("test".equals(method.getName())){ return method.invoke(accountService,args); } Object returnValue = null; try { transactionManager.beginTransaction(); returnValue = method.invoke(accountService, args); transactionManager.commit(); return returnValue; }catch (Exception e){ transactionManager.rollback(); throw new RuntimeException(e); }finally { transactionManager.release(); } } }); } }
-
-
Spring 中的 AOP
-
AOP 相关术语
- **Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点;
- **Advice(通知/增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知;通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知;
- Introduction:运行期为类动态地添加一些方法或Field;
- Target: 代理目标的对象;
- Weaving:增强应用到目标对象来创建新的代理对象的过程;Spring采用的是动态代理织入;
- Proxy:一个类被AOP织入增强后产生一个结果代理类;
- 切入点和通知的结合:
- 切面通常是需要被增强的野望 代码,
- 切入点方法一般是业务层,加强的方法一般是在切入点之前执行并且通过AOP进行配置增强
- 增强方式有两种配置通知的类型:1.配置前置通知,后置通知,异常通知,最终通知;2配置环绕通知
-