@wangzhuanyun
2020-08-24T03:18:31.000000Z
字数 10371
阅读 6951
ssm
Spring概述
Spring 是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。
Spring 框架是一个开源的 Java 平台,它最初是由 Rod Johnson 编写的,并且于 2003 年 6 月首次在 Apache 2.0 许可下发布。
Spring 是轻量级的框架,其基础版本只有 2 MB 左右的大小。
Spring 框架的核心特性是可以用于开发任何 Java 应用程序,但是在 Java EE 平台上构建 web 应用程序是需要扩展的。 Spring 框架的目标是使 J2EE 开发变得更容易使用,通过启用基于 POJO 编程模型来促进良好的编程实践。
Spring三大核心容器:Beans,Core,Context
Spring中两大核心技术,ICO(控制反转/依赖注入),AOP(面向切面编程)
引入Spring与SpringMVC的JAR
<spring.version>4.0.2.RELEASE</spring.version><!-- spring框架包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-oxm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency>
控制反转(其实就是把new对象放到了配置文件里)
将组件对象的控制权从代码本身转移到外部容器
组件化的思想:分离关注点,使用接口,不再关注实现
依赖的注入:将组件的构建和使用分开
实体类
public class HelloWorld {private String message;public void show(){System.out.println(message);}public void setMessage(String message) {this.message = message;}
创建xml配置文件引入头部,然后使用bean创建对象HelloWorld并参数赋值message
<bean id="helloWorld" class="com.hz.pojo.HelloWorld"><property name="message" value="Hello World!"/></bean>注意:相当于创建对象helloWorld = new HelloWorld();helloWorld.setMassage("Hello World!");
读取配置文件并运行
//使用ClassPathXmlApplicationContext读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");//使用getBean("bean中ID属性值")获取对象HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");helloWorld.show();
依赖注入
指 Spring 创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象
1 .引入另一个bean(使用ref属性)
dao层
public class UserDaoImpl {public void show(){System.out.println("输出UserDaoImpl信息");}
service层
public class UserServiceImpl {private UserDaoImpl userDao;public void serviceShow(){userDao.show();//调用userdao.show方法}public void setUserDao(UserDaoImpl userDao) {this.userDao = userDao;}
xml配置文件
<!--定义UserDaoImpl类--><bean id="userDaoImpl" class="com.hz.dao.UserDaoImpl"></bean><!--定义UserServiceImpl类--><bean id="userService" class="com.hz.service.UserServiceImpl"><!--使用ref属性将userDaoImpl注入userDao--><property name="userDao" ref="userDaoImpl"></property></bean>
2.构造函数注入(constructor-arg)
<bean id="userDao" class="dao.impl.UserDaoImpl" /><bean id="userService" class="service.impl.UserServiceImpl"><constructor-arg><ref bean="userDao" /></constructor-arg></bean>
3.p命名空间注入属性值
引入命名空间xmlns:p="http://www.springframework.org/schema/p"
对于直接量(基本数据类型、字符串)属性:p:属性名="属性值"
对于引用Bean的属性:p:属性名-ref="Bean的id"
<bean id="user" class="pojo.User" p:age="23" p:username="张三" /><bean id="userService" class="service.impl.UserServiceImpl"p:dao-ref="userDao" />
4.注入数组,字符串,集合.....各种类型
private String specialCharacter1; // 特殊字符值1private String specialCharacter2; // 特殊字符值2private User innerBean; // JavaBean类型private List<String> list; // List类型private String[] array; // 数组类型private Set<String> set; // Set类型private Map<String, String> map; // Map类型private Properties props; // Properties类型private String emptyValue; // 注入空字符串值private String nullValue = "init value"; // 注入null值<bean id="entity" class="entity.TestEntity"><!-- 使用<![CDATA[]]>标记处理XML特 殊字符 --><property name="specialCharacter1"><value><![CDATA[P&G]]></value></property><!-- 把XML特殊字符替换为实体引用 --><property name="specialCharacter2"><value>P&G</value></property><!-- 定义内部Bean --><property name="innerBean"><bean class="entity.User"><property name="username"><value>Mr. Inner</value></property></bean></property><!-- 注入List类型 --><property name="list"><list><!-- 定义List中的元素 --><value>足球</value><value>篮球</value></list></property><!-- 注入数组类型 --><property name="array"><list><!-- 定义数组中的元素 --><value>足球</value><value>篮球</value></list></property><!-- 注入Set类型 --><property name="set"><set><!-- 定义Set或数组中的元素 --><value>足球</value><value>篮球</value></set></property><!-- 注入Map类型 --><property name="map"><map><!-- 定义Map中的键值对 --><entry><key><value>football</value></key><value>足球</value></entry><entry><key><value>basketball</value></key><value>篮球</value></entry></map></property><!-- 注入Properties类型 --><property name="props"><props><!-- 定义Properties中的键值对 --><prop key="football">足球</prop><prop key="basketball">篮球</prop></props></property><!-- 注入空字符串值 --><property name="emptyValue"><value></value></property><!-- 注入null值 --><property name="nullValue"><null/></property></bean>
Spring IOC常用注解
@Component:实现Bean组件的定义
@Repository([实例化名称]) :用于标注DAO类
@Service([实例化名称]) :用于标注业务类
@Controller :用于标注控制器类
@Autowired+@Qualifier("userDao")等价于@Resource(name = "userDao")
使用注解前需先开启注解
<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/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd"><!-- 扫描包中注解标注的类 --><context:component-scan base-package="service,dao" />
Spring AOP 面向切面编程
如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用。
AOP 即 Aspect Oriented Program 面向切面编程(公共功能集中解决)
AOP 当中的概念:
切入点(Pointcut): 在哪些类,哪些方法上切入(where)
通知(Advice): 在方法执行的什么实际(when:方法前/方法后/方法前后)做什么(what:增强的功能)
切面(Aspect): 切面 = 切入点 + 通知,通俗点就是:在什么时机,什么地方,做什么增强!
织入(Weaving): 把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)
五中增强方式:
| 目录 | 说明 | 使用 |
|---|---|---|
| 前置增强 | 在一个方法执行之前,执行通知。 | before |
| 后置增强 | 在一个方法执行之后,不考虑其结果,执行通知。 | after-returning |
| 最终增强 | 在一个方法执行之后,只有在方法成功完成时,才能执行通知。 | after |
| 异常增强 | 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知 | after-throwing |
| 环绕增强 | 在一个方法执行之前,执行通知。 | around |
创建目标方法:
public class UserServiceImpl {//…省略代码public void addNewUser() {......}}
创建增强处理类UserServiceLogger
<!--使用joinPrint需要引入包 ,另外还需引入log4j包--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency>public class UserServiceLogger {//用于打印日志信息private static Logger log=Logger.getLogger(UserServiceLogger.class);public void before(JoinPoint jp) {log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName() + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));}public void afterReturning(JoinPoint jp, Object result) {log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName() + " 方法。方法返回值:" + result);}}
引入xml头部
xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd<aop:config><!--定义切入点--><aop:pointcut id="pointcut" expression="execution(public void show())"/><!--织入增强处理--><aop:aspect ref="serviceLogger"><!--使用前置增强,将切入点与before方法绑定--><aop:before method="before"pointcut-ref="pointcut"></aop:before><!--使用后置增强,将切入点与before方法绑定 returning 返回参数接收--><aop:after-returning method="afterReturning"pointcut-ref="pointcut" returning="result"/></aop:aspect></aop:config>execution表达式匹配规则:public * addNewUser(entity.User): “*”表示匹配所有类型的返回值。public void *(entity.User): “*”表示匹配所有方法名。public void addNewUser(..): “..”表示匹配所有参数个数和类型。* com.service.*.*(..):匹配com.service包下所有类的所有方法。* com.service..*.*(..):匹配com.service包及其子包下所有类的所有方法
AOP注解
开启注解
<aop:aspectj-autoproxy>**/*** 使用注解定义切面*/@Aspect@Componentpublic class UserServiceLogger {private static final Logger log = Logger.getLogger(UserServiceLogger.class);@Pointcut("execution(* service.UserService.*(..))")public void pointcut() {}@Before("pointcut()")public void before(JoinPoint jp) {log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));}@AfterReturning(pointcut = "pointcut()", returning = "returnValue")public void afterReturning(JoinPoint jp, Object returnValue) {log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()+ " 方法。方法返回值:" + returnValue);}}
AOP事务处理
导入tx和aop命名空间
定义事务管理器DataSourceTransactionManager并为其注入数据源Bean
<!--定义事务采用JDBC管理事务--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><tx:advice id="txAdvice"><tx:attributes><tx:method name="find*" propagation="SUPPORTS" /><tx:method name="add*" propagation="REQUIRED" /><tx:method name="del*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="*" propagation="REQUIRED" /></tx:attributes></tx:advice> --><!-- 定义切面 --><!-- <aop:config><aop:pointcut id="serviceMethod"expression="execution(* com.hz.service..*.*(..))" /><aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /></aop:config>
tx:method其他属性
timeout:事务超时时间,允许事务运行的最长时间,以秒为单位。默认值为-1,表示不超时
read-only:事务是否为只读,默认值为false
rollback-for:设定能够触发回滚的异常类型Spring默认只在抛出runtime exception时才标识事务回滚
可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开no-rollback-for:设定不触发回滚的异常类型
Spring默认checked Exception不会触发事务回滚
可以通过全限定类名指定不需回滚事务的异常,多个类名用英文逗号隔开
propagation事务传播机制
propagation_requierd(默认):如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作
事务注解
开启注解
<tx:annotation-driven />
@Transactional注解使用
@Transactional //类中开启事务@Service("userService")public class UserServiceImpl{//使用事务@Transactional(propagation = Propagation.REQUIRED)public boolean addNewUser(User user) {....}}
Spring 能帮我们做什么
①.Spring 能帮我们根据配置文件创建及组装对象之间的依赖关系。
②.Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
③.Spring 能非常简单的帮我们管理数据库事务。
④.Spring 还提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板来方便数据库访问。
⑤.Spring 还提供与第三方Web(如Struts1/2、JSF)框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。
⑥.Spring 能方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)。