SSM框架
Spring MVC + Spring + MyBatis
Spring框架优点
学习于狂神的B站视频!!!
- 是一个开源免费的框架;
- 轻量级、非入侵式的框架;
- 控制反转(IOC),面向切面编程(AOP);
- 支持事务处理,对框架整合的支持;
控制反转(IOC)
- IOC:传统的代码,程序是主动创建对象,控制权在开发者手中;使用Spring后,对象是由Spring创建;
- 依赖注入(DI):其和IOC是对同一事情的不同描述,也就是说程序不再具有主动性,而是变成了被动接受对象;
- 总结:
- 这种思想下,开发者不用再去管理对象的创建了,系统耦合性大大降低,可以更加专注于业务的实现;
- 现在彻底不需要在原程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改;
- 对象由Spring创建,管理,装配(为对象设置属性)!
创建对象
- 默认是使用无参构造器创建对象;
<!--这个是默认创建对象的方式--> <bean id="construct" class="com.thiszc.pojo.User"> <property name="name" value="thiszc"/> </bean>
- 通过下标(index)创建
<bean id="construct2" class="com.thiszc.pojo.User"> <constructor-arg index="0" value="下标创建"/> </bean>
- 通过类型(type)创建
<bean id="construct3" class="com.thiszc.pojo.User"> <constructor-arg type="java.lang.String" value="通过类型创建"/> </bean>
- 通过参数名(name)来创建
<!--如果有多个构造器,那么和方法重载思想是一样的,取决于你传入的参数列表。。。--> <bean id="construct4" class="com.thiszc.pojo.User"> <constructor-arg name="name" value="通过参数名来创建"/> <constructor-arg name="age" value="2"/> </bean>
xml配置文件
- bean 模块配置
<!-- id: 对象名(以后称为bean) class: 类的全路径名 name : 为bean起别名 --> <bean id="user2" class="com.thiszc.pojo.UserT" name="userT, u2 u3; u4"> <constructor-arg name="name" value="123"/> </bean>
- alias 配置:用于给bean起别名
<alias name="construct" alias="thiszc"/>
- import:在总配置文件中导入其他子配置文件,总配置文件中可以使用子配置文件的配置;多用于协同开发。
<import resource="beans1.xml"/> <import resource="beans2.xml"/> <import resource="beans3.xml"/>
依赖注入
- 构造器注入:上面的创建对象就是使用构造器注入方式,这里不在赘述。
- Set方式注入
- 依赖:bean的创建依赖于容器;
- 注入:bean中的所有属性,由容器来注入;
- 对于集合类型的数据,只需在标签中添加集合名字即可,其中map类型和prop类型有些特殊,它们被表示成键值对形式;
<!--普通值注入 通过value--> // 常用 <property name="name" value="thiszc"/> <!--bean注入 通过ref--> // 常用 <property name="address" ref="address"/> <!--数组注入--> <property name="books"> <array> <value>java 教程</value> <value>C++ 教程</value> <value>Python 教程</value> </array> </property> <!--List注入--> <property name="hobbys"> <list> <value>coding</value> <value>game</value> <value>film</value> </list> </property> <!--Map注入--> <property name="card"> <map> <entry key="学生证" value="123"/> <entry key="校园卡" value="456"/> </map> </property> <!--Set注入--> <property name="games"> <set> <value>LOL</value> <value>King</value> </set> </property> <!--null注入--> <property name="wife"> <null/> </property> <!--properties注入可以用于连接数据库(key="driver"...)--> <property name="info"> <props> <prop key="学号">159357</prop> <prop key="姓名">thiszc</prop> <prop key="专业">net</prop> <prop key="院系">Net</prop> </props> </property>
- p命名空间注入和c命名空间注入
- 需要导入xlmns约束
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--p命名空间注入,可以直接注入属性值--> <bean id="user" class="com.thiszc.pojo.User" p:name="p命名" p:age="21"/> <!--c命名空间注入,可以通过构造器注入--> <bean id="user2" class="com.thiszc.pojo.User" c:name="c命名" c:age="22"/> </beans>
- 需要导入xlmns约束
bean作用域
- 单例模式(Spring默认机制)
<bean id="user2" class="com.thiszc.pojo.User" c:name="c命名" c:age="22" scope="singleton"/>
- 原型模式(每次从容器中get的时候,都会产生一个新的对象)
<bean id="user2" class="com.thiszc.pojo.User" c:name="c命名" c:age="22" scope="prototype"/>
- 其余的 request、session、application 只会在web开发中使用到。
Bean自动装配
- 通过byName(bean id名字 需要保证全局唯一;id不可以省略,byType可以省略)
<!-- byName: 会自动在容器上下文中查找,和自己对象的set方法的引用变量名字一致的bean id,如果有就自动装配,否则会报空指针异常; --> <bean id="people" class="com.thiszc.pojo.People" autowire="byName"> <property name="name" value="thiszc"/> </bean>
- 通过byType:(需要保证上下中bean类型全局唯一,byName没有这种限制)
<!-- byType: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanID的类型,如果有就自动装配,需要保证每个类型是全局唯一的,否则会报错 --> <bean id="people" class="com.thiszc.pojo.People" autowire="byType"> <property name="name" value="thiszc"/> </bean>
- 使用注解自动装配
- jdk1.5支持注解,spring2.5支持注解
- 配置注解的支持 导入context aop约束
<?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" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:annotation-config/> <bean id="cat" class="com.thiszc.pojo.Cat"/> <bean id="dog" class="com.thiszc.pojo.Dog"/> <bean id="people" class="com.thiszc.pojo.People"/> </beans>
- 使用@Qualifier(value=“id”) 配合@Autowired来限定装配的对象,如果自动装配环境比较复杂;
- 只使用@Resource(name=“id”)这个注解也是可以的;
- @Resource 和@Autowired区别:
- 都是用来实现自动装配的;都可以放在属性上面;
- @Autowired通过byType方式实现,要求对象必须存在 【常用】
- @Resource默认通过byName方式实现,如果找不到名字,则通过byType实现,如果两个都找不到就会报错;
- @Resource相当于@Autowired+@Qualifier(value=“id”)
使用注解开发
-
@Component 放于类User上面,说明User被spring管理
其等价于<bean id="user" class="com.thiszc.pojo.User"/>
-
@Value(“中国”):用于属性注入,可以放到属性和set方法上面
其等价于<property name="name" value="中国"/>;
-
衍生注解
- @Component
- @Controller
- @Repository
- @Service
- 都是用于将类注册到Spring中进行装配 Bean
-
作用域
- @Scope(“singleton”) 表示类是单例模式 “prototype” 表示为原型模式;
-
xml配置文件与注解:
- xml万能,适用于任何场合,维护简单方便;
- 注解不是自己的类使用不了,维护相对复杂;
- xml 用来管理bean,注解用于属性注入。
- 使用注解的话,必须让注解生效和开启注解支持
<!--指定要扫描的包,这个包下的注解就会生效--> <context:component-scan base-package="com.thiszc"/> <context:annotation-config/>
使用Java方式配置Spring
- 不再使用xml配置文件完成类的管理装配等操作;
- 增加一个配置类,使用@Configuration注解;
- @Configuration:代表这是一个配置类,和之前的beans.xml文件具有类似的功能
- 配合@ComponentScan(“package name”)注解:表示扫描指定的包
-
@Bean // 注册一个bean, 相当于xml文件中写的bean标签; // 方法名字相当于bean标签中的id属性; // 方法返回类型相当于bean标签中的class对象; // 方法返回值就是要注入到bean的对象;
- 完整实例
// 代表这是一个配置类,和之前的beans.xml文件具有类似的功能 @Configuration @ComponentScan("com.thiszc.pojo") public class MyConfig { @Bean // 注册一个bean, 相当于xml文件中写的bean标签; // 方法名字相当于bean标签中的id属性; // 方法返回类型相当于bean标签中的class对象; // 方法返回值就是要注入到bean的对象; public User getUser(){ return new User(); }
- 需要通过
ApplicationContext context = new AnnotationConfigApplicationContext(配置类.class);
来获取对象 @Import()
:如果有多个配置文件,可以通过@Import(其他配置类.class)
注解来引入;达到将多个配置类合并的目的;类似于xml配置中的<import >
标签;
代理模式
- 为什么要学习代理模式?是Spring AOP的底层实现;
- 分类:
① 静态代理:
② 动态代理: - 静态代理
- 一般步骤
① 抽象角色:一般会使用接口或者抽象类来解决;
② 真实角色:被代理的角色;
③ 代理角色:代理真实角色,需要做一些附属操作,不然也没有存在的意义;
④ 客户:访问代理对象的人; - 好处:
- 可以使真实角色的操作更加纯粹!不用关注一些公共的业务;
- 公共业务交给代理角色,实现了业务分工;
- 公共业务发生扩展时,方便集中管理;
- 缺点:
- 一个真实角色就会有一个代理角色,代码量翻倍,开发效率变低;
- 一般步骤
- 动态代理:
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的,
- 分为两大类:
- 基于接口:JDK动态代理 【重点】
- 基于类:cglib
- 基于字节码实现 (javasist)
- 优点
- 所有静态代理拥有的优点
- 一个动态代理类代理的是一个接口,一般就是一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口
AOP
-
面向切面编程示意图
-
execution()是最常用的切点函数,语法如下:
- execution(): 表达式主体。
- 第一个*号:表示返回类型,*号表示所有的类型。
- 包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
- 第二个*号:表示类名,*号表示所有的类。
- *(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个点表示任何参数。
-
AOP在Spring中的作用:
- 提供声明式事务;允许用户自定义切面;
- 横切关注点:与业务逻辑无关,但是需要关注的部分,如日志,安全,缓存,事务等等…
- 切面(Aspect):横切关注点,被模块化的特殊对象,它是一个类;
- 通知(Advice):切面必须要完成的工作,也就是类中的一个方法;
- 目标(Target):被通知对象;
- 代理(Proxy):向目标对象应用通知之后创建的对象;
- 切入点(PointCut):切面通知执行的"地点"的定义;
- 连接点(JoinPoint):与切入点匹配的执行点;
Spring 整合 MyBatis
- 一般步骤:
- 编写数据源配置;
- sqlSessionFactory;
- sqlSessionTemplate;
- 给接口增加实现类;
- 将自己写的实现类,注入到Spring中;
- 测试;
Spring配置事务
<!--transaction config-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--<tx:method name="add" propagation="REQUIRED"/>-->
<!--<tx:method name="delete" propagation="REQUIRED"/>-->
<!--<tx:method name="update" propagation="REQUIRED"/>-->
<!--<tx:method name="query" read-only="true"/>-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.thiszc.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>