spring
id : 唯一标识 (map的key)
class: 指定当前需要创建对象的权限定类名
name : 起别名
scope: (默认spring中的的beanshi 单列)
-
整合 : 就是把 相应技术的关键技术对象存放到 spring的容器中
- redis :
jedis
mybatis : Resources
SqlsessionFactoryBuilder
SqlsessionFactroy
Sqlsession
spring整合druid
-
原始使用DataSource
public static void main(String[] args) throws SQLException { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/db1"); dataSource.setUsername("root"); dataSource.setPassword("root"); DruidPooledConnection connection = dataSource.getConnection(); }
-
步骤
-
导包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency> </dependencies>
-
spring配置文件编写
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.200.129:3307/db1"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
-
mybatis做什么?
-
需要的文件
- applicationContext.xml
- dao接口以及对应的映射配置文件
-
作用:操作数据库
-
mybatis本身处理连接池工作(需要数据库连接池)
<!--加载perperties配置文件的信息--> <context:property-placeholder location="classpath:*.properties"/> <!--加载druid资源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
-
mybatis需要Sqlsession对象(需要一个创建Sqlsession的工厂)
<!--spring整合mybatis后控制的创建连接用的对象--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.itheima.domain"/> </bean>
-
dao层动态代理实现(动态代理实现的bean必须由spring管理)
- 这些接口的实现类(bean)是由mybatis创建的
<!--加载mybatis映射配置的扫描,将其作为spring的bean进行管理--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.itheima.dao"/> </bean>
-
注解
注解是什么
注解只不过是一个标记 存储了少量的内容信息 具体的功能是由 具体的框架实现
spring配置bean的方式
1 配置文件 方式 bean标签配置
2 注解配置 加载类上 (只写注解不会生效,一定要扫描对应的包)
1 @Component @Controller @Service @Repository
注入bean 写在 类上面讲一个类的实例加入 spring容器
2 @Scope 指定他他的范围
3 @post Contructor @ PreDestory
3 @bean 加在方法 上
@Component
public class JdbcConfig {
@Bean
public DataSource getDataSource() {
DataSource dataSource = new DruidDataSource();
return dataSource;
}
}
注解启动时使用注解的形式替代xml 配置 ,将复杂的spring配置文件从工程中 彻底消除
ben 用的四个注解
1 @Component @Controller @Service @Repository
@Controller @Service @Repository 功能同 @Component
@Component("…") 代替 <ben id= class= >
类注解 @scope 代替属性 @scope (prototype)
@scope (singleton) 以后的主流 设定ben 的作用域.
@ value (默认) 定义bean 的访问id
启动注解驱动
<context:component-scan base-package=“com”/>
有了它就可以运行注解
加载第三方资源
名称 @bean 类型 方法注解 位置 定义在方法上方
作用 设置该方法的返回值 作为spring管理的bean
说明 : 因为第三方bean无法在其 源码上进行修改 使用@bean解决第三方bean的引入问题
@bean 所在的类必须被spring扫描加载 否则该注解无法生效
该注解用于 替代xml配置中的静态工厂实例工厂传谷歌建bean 不区分方法静态或非静态
public class JDBCConfig {
@Bean("dataSource")
public static DruidDataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://192.168.72.136:3306/db11");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
常用户注解 ben 的非引用类型属性注入
名称 @value
类型 属性注解 方法注解
位置 属性定义上方 方法定义上方
作用 设置对应属性值 或对方法进行传参
仅支持非引用类型
ben 的引用类型属性注入
名称 @ Autowired 自动装配 @Qualifier 指定引用那个id
类型 : 属性注解 方法注解
位置: 属性定义上方 方法定义上方
作用: 设置 对应属性的对象或对方法进行应用类型传参
说明 : @Autowired 默认按类型装配 指定@Qualifie后可以指定自动装配的 bean的id
@primary 优先加载 只能写一个 只能用一次
一般选择哪个运行 就用@ Qualifer
@inject @ Named @Resource 功能与@Autowired和@ Qualifier 完全相同
加载Properties文件
名称 @propertySource文件
类型 类注解
位置 : 类定义上方
作用: 加载Properties 文件中属性值
说明: 不支持* 通配格式 一旦加载所有spring控制的bean中均可使用对应属性值
@PropertySource(value={"classpath:jdbc.properties"}
value 可以省略
如果有多个 必须用大括号包起来
@PropertySource(value={"classpath:jdbc.properties","classpath:abc.properties"}
如果加多个没找到 输入 ignoreResourceNotFound = true) 就可以正常运行
纯 注解格式
名称 @ Configuration @ ConmponentScan
类型 类注解
位置 类定义上方
作用 设置当前类为Spring 核心配置加载类
说明 核心配合 类用于 替换spring核心配置文件 此类可以设置空的 不设置变量属性 @bean扫描工作中使用注解
@ ComponentScan 替代
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
测试用 ApplicationContext ctx =new AnnotationConfigApplicationContext(SpringConfig.class);
第三方bean 配置与管理
名称 @ import
类型 类注解
位置 类定义上方
作用 导入 第三方bean作为spring控制的资源
说明 @ import 注解在同一个类上 仅允许添加一次 如果需要导入多个 使用数组形式进行设定
在被导入 的类中可以继续使用@import导入其他资源
@Import(JDBCConfig.class)
bean加载控制
依赖加载
名称: @ DependsOn
类型 类注解 方法注解
位置 bean定义的位置 类上或方法上
作用 控住bean 的加载顺序 使其在指定bean加载完毕以后在加载
说明:配置在方法上 使 @ DependsOn指定 的bean优先于@bean配置的bean进行加载
配置在类上 使用 @ DependsOn 指定的bean优先于当前类所有@bean配置的bean进行配置
配置在类上 使用 @ DependsOn 指定的bean优先于@Component 等配置的bean 进行加载
@order 多个中类的配置出现后, 优先加载系统及的 然后加载业务级的 避免细粒度的加载控制
Aop
1 IOC 容器控制反转
2 Aop 方法增强 ,面向切面编程
1 动态代理
2 反射
// 动态代理 JDK 动态代理 需要有实现的接口
cglb 不要接口 用id 获取
-4.配置AOP
<aop:config>
5.配置切入点
<aop:pointcut id="pt" expression="execution(* com.itheima. *..*(..))"/>
6.配置切面(切入点与通知的关系)
<aop:aspect ref="myAdvice">
7.配置具体的切入点对应通知中那个操作方法-->
<aop:before method="function" pointcut-ref="pt"/>
<aop:before method="printCurTime" pointcut-ref="pt"/>
<aop:after-returning method="printCurTime" pointcut-ref="pt" returning="ret"/>
</aop:aspect>
</aop:config>
切入点表达式-- 通配符
- *单个独立的任意符号可以独立出现
- … 多个连续的任意符号
aop 的通知类型 5中
1 befor 前置通知 应用 数据效验 2 after 后置通知现场清理 3 afterReturing 返回后通知 有异常 就不执行了 返回值相关处理
4 after-throwing 抛出异常后通知 对原始方法中出现的异常信息进行处理
5 around 环绕 加参数 ProceedingJoinPoint pjp.proceed();调用原来的方法 根据方法位置区分前后 注意有一条红线报错 是抛异常还是 try/Cathy
通知中获取参数 JoinPoint
public class AopAdivce3 {
public void before(JoinPoint jp ){
Object[] args = jp.getArgs();
System.out.println("before"+args[0]);
}
获取返回值
around afterReturing 只有这两个可以拿到返回值 要加一个参数 objet 因为不知道返回的是什么类型
public void after(Object ret){
System.out.println("after"+ret);
}
<aop:after-returning method="afterReturing" pointcut-ref="pt" returning="ret"/>
获取异常 参数 Throwable
public void afterThrowing(Throwable t){
System.out.println("afterThrowing"+t.getMessage());
}
<aop:after-throwing method="afterThrowing" pointcut-ref="pt" throwing="t"/>
注解
配置 <aop:aspectj-autoproxy/>//开启AOP
@Aspect标记通知在类上这个类就是切面了
@pointcut 定义需要增强哪些方法
具体通知
@Before @ After @Afterthrowing @AfterRetuin
@Component spring控制的资源
@Aspect 切面
@public class AopAdavice{}
@Pointcut("execution(* *(..))") 切入点 放在方法上
public void pt(){}
配置转为注解 建一个类 config 代替applicationContext.xml
1 @Configuration 相当于这个类为配置文件
2 //<context:component-scan base-package="com.itheima"/>
@ComponentScan("com.itheima") 扫描包的意思 代替
3//<aop:aspectj-autoproxy/> 开启AOP 自动代理
@EnableAspectJAutoProxy
4<bean id="userService" class="com.itheima.service.Impl.UservServiceImpl"/>
@Component 代替
事务
要么同时成功 要么同事失败
原子性 指事务是一个不可分割的整体 其中的操作要么全执行 要么全不执行
一致性 事务前后数据的完整性必须保持一致性
隔离性 事务的隔离性 不能被其他的事务的操作数据所干扰
持久性 一个事务一但提交 对数据库中的数据是持久性的
Connectioncon
commit 提交
rollback 回滚
<!--定义事务管理的通知类-->
<tx:advice id="txAdvice" transaction-manager="txManager">
编程式事务 private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public Object transactionManager(ProceedingJoinPoint pjp) throws Throwable {
//开启事务
PlatformTransactionManager ptm = new DataSourceTransactionManager(dataSource);
//事务定义
TransactionDefinition td = new DefaultTransactionDefinition();
//事务状态
TransactionStatus ts = ptm.getTransaction(td);
Object ret = pjp.proceed(pjp.getArgs());
//提交事务
ptm.commit(ts);
return ret;
aop 改造 编程式事务
声明式事务 注解
声明事务注解方式
开启注解驱动
配置事务的属性(@Transactional)
接口(主流)
类
方法
@Transactional 放在接口上 代替{ <!--<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method
name="transfer"
read-only="false"
timeout="-1"
isolation="DEFAULT"
no-rollback-for=""
rollback-for=""
propagation="REQUIRED"
/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.itheima.service.*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
--> }
在配置里边 这个声明用注解驱动
<tx:annotation-driven transaction-manager="txManager"/>
声明事务纯注解
1 @Configuration 相当于这个类为配置文件
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JDBCConfig.class,MyBatisConfig.class})
@EnableTransactionManagement //开启aop 代理
public class SpringConfig {
}
config类
MyBatisConfig
public class MyBatisConfig {
public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){
SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
sfb.setTypeAliasesPackage("com.itheima.domain");
sfb.setDataSource(dataSource);
return sfb;
}
public MapperScannerConfigurer getMapperScannerConfigurer(){
MapperScannerConfigurer msf = new MapperScannerConfigurer();
msf.setBasePackage("com.itheima.dao");
return msf;
}
JDBCConfig
public class JDBCConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")
public DataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
/设定spring专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//设定加载的spring上下文对应的配置
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(){
accountService.transfer("Jock1","Jock2",100D);
}
}
)
private String password;
@Bean("dataSource")
public DataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
/设定spring专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//设定加载的spring上下文对应的配置
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer(){
accountService.transfer("Jock1","Jock2",100D);
}
}