标签:单例 手动 asp res pat instance auto sign throwable
官方文档 https://spring.io/projects/spring-framework#learn
控制反转是一种通过描述并通过第三方去生产或获取特定对象的方式
<bean id="user" class="com.pojo.User">
<property name="name" value="张三"/>
</bean>
<!-- 第一种根据index参数下标设置 -->
<bean id="user1" class="com.pojo.User">
<!-- index指构造方法 , 下标从0开始 -->
<constructor-arg index="0" value="张三"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="user2" class="com.pojo.User">
<!-- name指参数名 -->
<constructor-arg name="name" value="李四"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="user3" class="com.pojo.User">
<constructor-arg type="java.lang.String" value="王五"/>
<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="user" alias="userNew"/>
<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
<import resource="{path}/beans.xml"/>
要求被注入的属性,必须有set方法,set方法的方法名由set + 属性首字母大写,如果属性是boolean类型,没有set方法,是 is
常量注入
<bean id="student" class="com.pojo.Student">
<property name="name" value="小明"/>
</bean>
Bean注入
<bean id="addr" class="com.pojo.Address">
<property name="address" value="重庆"/>
</bean>
<bean id="student" class="com.pojo.Student">
<property name="address" ref="addr"/>
</bean>
数组注入
<bean id="student" class="com.pojo.Student">
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
</array>
</property>
</bean>
List注入
<property name="hobbys">
<list>
<value>听歌</value>
<value>看电影</value>
</list>
</property>
Map注入
<property name="card">
<map>
<entry key="中国邮政" value="456456456465456"/>
<entry key="建设" value="1456682255511"/>
</map>
</property>
set注入
<property name="games">
<set>
<value>LOL</value>
<value>BOB</value>
</set>
</property>
Null注入
<property name="wife"><null/></property>
Properties注入
<property name="info">
<props>
<prop key="性别">男</prop>
<prop key="姓名">小明</prop>
</props>
</property>
导入约束:xmlns:p="http://www.springframework.org/schema/p"
<!--P(属性: properties)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.pojo.User" p:name="小明" p:age="18"/>
导入约束:xmlns:c="http://www.springframework.org/schema/c"
<!--C(构造: Constructor)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.pojo.User" c:name="小明" c:age="18"/>
<bean id="user" class="com.pojo.User" autowire="byName">
<property name="str" value="小明"/>
</bean>
通过set方法查找
<bean id="user" class="com.pojo.User" autowire="byType">
<property name="str" value="小明"/>
</bean>
需要同一类型的对象在Spring容器中唯一
按类型自动装配
public class User {
@Autowired
private Cat cat;
public Cat getCat() {
return cat;
}
}
此时配置文件内容
<!-- 开启注解支持 -->
<context:annotation-config/>
<bean id="cat" class="com.pojo.Cat"/>
<bean id="user" class="com.pojo.User"/>
默认为true,@Autowired(required=false)说明对象可以为null
@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
@Qualifier不能单独使用
@Autowired
@Qualifier(value = "cat2")
private Cat cat;
- @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
- 其次再进行默认的byName方式进行装配;
- 如果以上都不成功,则按byType的方式自动装配。
- 都不成功,则报异常。
@Resource(name = "cat2")
private Cat cat;
它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。
配置文件中引入context约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
<!--指定注解扫描包-->
<context:component-scan base-package="com.pojo"/>
扫描过滤
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>>//包含
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>>//排除
过滤方式
annotation:注解
assignable:指定class或interface的全名
aspectj:AspectJ语法
regex:正则
如果配置了 <context:component-scan>
那么 <context:annotation-config/>
标签就可以不用再xml中配置了,因为前者包含了后者
@Component
@Controller:web层
@Service:service层
@Repository:dao层
@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
@Value("小明")
// 相当于配置文件中 <property name="name" value="小明"/>
public String name;
}
或者在set方法上添加@value("值")
@Controller("user")
@Scope("prototype")
public class User {
@Value("小明")
public String name;
}
@Configuration//代表这是一个配置类
@Import(MyConfig2.class)//导入合并其他配置类,类似于配置文件中的 inculde 标签
@ComponentScan("com.pojo")//指定扫描的包
public class MyConfig {
@Bean(name="dog2")//通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!也可以手动指定名称
public Dog dog(){
return new Dog();
}
}
官方文档https://docs.spring.io/spring/docs/5.2.1.RELEASE/spring-framework-reference/core.html#aop
通知类型 | 名称 | 说明 |
---|---|---|
前置通知 | Before advice | 连接点前执行,除非抛出异常,否则不能阻止方法的继续执行 |
后置通知(最终通知) | After (finally) advice | 连接点执行完成后执行,总会执行 |
正常返回通知 | After returning advice | 在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行 |
异常返回通知 | After throwing advice | 在连接点抛出异常后执行 |
环绕通知 | Around advice | 连接点前后执行 |
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
* 表示任意一个
.. 表示多个
xml中连接子表达式用 and, or, not
注解中用 &&, ||, !
<!-- 声明开始aop的配置 -->
<aop:config>
<!-- 配置切面。
id:唯一标识,
ref:引用配置好的通知类bean的id
-->
<aop:aspect id="txAdvice" ref="txManager">
<!-- 配置切入点表达式。就是指定对哪些类的哪些方法进行增强。
expression:用于定义切入点表达式,
id:切入点唯一标识
-->
<aop:pointcut expression="execution(表达式)" id="pt1"/>
<!-- 前置通知。
method:指定通知类中的增强方法名称;
pointcut:指定切入点表达式
pointcut-ref:指定切入点的表达式的引用
-->
<aop:before method="beginTransaction" pointcut-ref="pt1"/>
<!-- 正常返回通知
returning:获取返回值传递到对应的参数上,method的方法必须声明一个名为retVal的参数
-->
<aop:after-returning method="commit" returning="retVal" pointcut-ref="pt1"/>
<!-- 异常返回通知
throwing:获取异常传递到对应的参数上,method的方法必须声明一个名为dataAccessEx的参数
-->
<aop:after-throwing method="rollback" throwing="dataAccessEx" pointcut-ref="pt1"/>
<!-- 最终通知 -->
<aop:after method="release" pointcut-ref="pt1"/>
<!-- 环绕通知
通常情况独立使用
-->
<aop:advisor method="release" pointcut-ref="pt1"/>
</aop:aspect>
</aop:config>
@Component("txManager")
@Aspect
public class AnnotationPointcut {
@Before("execution(* com.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("---------方法执行前---------");
}
@After("execution(* com.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("---------方法执行后---------");
}
@Around("execution(* com.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
System.out.println("签名:"+jp.getSignature());
//执行目标方法proceed
Object proceed = jp.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
}
在 spring 配置文件中开启 spring 对注解 AOP 的支持
<!-- 开启 spring 对注解 AOP 的支持 -->
<aop:aspectj-autoproxy/>
不使用 XML 的配置方式
@Configuration
@ComponentScan(basePackages="...")
@EnableAspectJAutoProxy
public class SpringConfiguration {
}
aop:aspectj-autoproxy:说明
通过aop命名空间的
官方文档:http://mybatis.org/spring/zh/index.html
Maven依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
MyBatis-Spring | MyBatis | Spring 框架 | Spring Batch | Java |
---|---|---|---|---|
2.0 | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
1.3 | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
引入Spring配置文件的beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
配置数据源替换mybatis的数据源
<!--配置数据源:数据源有非常多,可以使用第三方的,也可使使用Spring的-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
配置SqlSessionFactory,关联MyBatis
<!--配置SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--关联Mybatis-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/dao/*.xml"/>
</bean>
注册SqlSessionTemplate,关联SqlSessionFactory
<!--注册sqlSessionTemplate , 关联sqlSessionFactory-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--利用构造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
增加Dao接口的实现类;私有化SqlSessionTemplate
public class UserDaoImpl implements UserMapper {
//sqlSession不用我们自己创建了,Spring来管理
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
注册bean实现
<bean id="userDao" class="com.kuang.dao.UserDaoImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
官方文档http://mybatis.org/spring/zh/sqlsession.html#SqlSessionDaoSupport
原子性(atomicity)
事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用
一致性(consistency)
一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中
隔离性(isolation)
可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏
持久性(durability)
事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中
Spring支持7种传播行为
spring中事务的隔离级别可以通过隔离属性指定
DEFAULT | 使用底层数据库的默认隔离级别,大部分数据库,默认隔离级别都是READ_COMMITED |
READ_COMMITED | 只允许事务读取已经被其他事务提交的更改,可以避免脏读,但不可重复读和幻读问题仍然可能出现 |
READ_UNCOMMITED | 允许事务读取未被其他事务提交的更改。脏读,不可重复读,幻读都可能会出现 |
REPEATABLE_READ | 确保事务可以多次从一个字段中读取相同的值。在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但是幻读的问题依然存在 |
SERIALIZABLE | 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入,更新,删除。所有的并发问题都能避免,但是性能比较低。 |
注意:事务的隔离级别需要底层数据库引擎的支持,而不是应用程序或者框架的支持
导入 aop 和 tx 两个名称空间
步骤:
配置事务管理器
<!-- 配置一个事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入 DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
配置事务的通知引用事务管理器
<!-- 事务的配置 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"></tx:advice>
配置事务的属性
<!--在 tx:advice 标签内部 配置事务的属性 -->
<tx:attributes>
<!-- 指定方法名称:是业务核心方法
read-only:是否是只读事务。默认 false,不只读。
isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
propagation:指定事务的传播行为。
timeout:指定超时时间。默认值为: -1。永不超时。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。没有默认值,任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回滚。没有默认值,任何异常都回滚。
-->
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
配置 AOP 切入点表达式
<!-- 配置 aop -->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut expression="execution(* com.service.impl.*.*(..))" id="pt1"/>
</aop:config>
配置切入点表达式和事务通知的对应关系
<!-- 在 aop:config 标签内部: 建立事务的通知和切入点表达式的关系 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
配置事务管理器并注入数据源
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
在业务层使用 @Transactional 注解
@Service("accountService")
@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
public class AccountServiceImpl implements IAccountService {
...
}
在配置文件中开启 spring 对注解事务的支持
<!-- 开启 spring 对注解事务的支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Configuration
@EnableTransactionManagement
public class SpringTxConfiguration {
//里面配置数据源,配置 JdbcTemplate,配置事务管理器
}
标签:单例 手动 asp res pat instance auto sign throwable
原文地址:https://www.cnblogs.com/yxmhl/p/11795766.html