介绍
-
轻量级
-
低侵入式
一. IOC
-
IOC:控制反转,将对象的创建、初始化、销毁等过程交给spring容器来管理
-
搭建Spring框架的步骤
-
导入jar包:
-
书写spring框架的主配置文件(applicationConetext.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/bean http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- bean标签:将需要创建对象的类交给spring容器 class属性:某个的具体路径 id属性:为当前标签取一个标识符 --> <bean id="Dog" class="cn.java.entity.Dog"></bean> <bean id="Cat" class="cn.java.entity.Cat"></bean> </beans>
-
启动框架,直接测试
public static void main(String[] args) { //启动框架 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取spring容器中的某一个创建好的对象 Dog dog1 = (Dog) context.getBean("Dog"); dog1.ation(); }
-
1.1. spring的单例和多例
-
单例:在new对象时,new出的对象都指向同一块地址,既都是同一个对象
-
多例:
<!-- scope属性:指定单例和多例 常用值: singlton -- 单例 prototype -- 多例 --> <bean id="Duck" class="cn.java.singleton2.Duck" scope="prototype"></bean>
-
取别名
<!-- alias标签:为某一个Bean对象取别名 name属性:与bean标签中的id值保持一致 alias属性:别名 --> <alias name="Duck" alias="鸭子"/>
拆分配置文件
当实体类太多时,用一个配置文件则内容过于庞大,可以用import标签拆分配置文件。
在主配置文件上
<import resource="cn/java/ioc1/applicationContext-ioc1.xml"/>
<import resource="cn/java/singleton2/applicationContext-singleton2.xml"/>
1.2. spring中的懒加载和非懒加载
-
非懒加载:
· 缺点:容器启动时立马创建对象,因此消耗内存资源
· 优点:可以提前帮助程序员发现错误 -
懒加载:
· 优点:节省内存资源<!-- lazy-init属性:指定框架创建对象的时机 常用值: default -> 非懒加载:spring框架启动时立即创建对象 false -> 非懒加载 true -> 懒加载:使用时创建对象 --> <bean id="Pig" class="cn.java.lazy3.Pig" lazy-init="true"></bean>
1.3. 初始化与销毁
<bean idbean id="Mouse" class="cn.java.initAndDestroy4.Mouse" init-method="init" destroy-method="destory"></bean>
二. DI
-
DI:依赖注入,给对象的属性赋值
- 通过构造器注入赋值
<!-- 第一种情况:该对象中的属性是基本类型 --> <bean id="Penguin" class="cn.java.di5.Penguin"> <constructor-arg index="0" type="java.lang.String" value="Q妹"></constructor-arg> <constructor-arg index="1" type="java.lang.String" value="母"></constructor-arg> <constructor-arg index="2" type="java.lang.Integer" value="2"></constructor-arg> </bean> <!-- 第二种情况:该对象中的属性有自定义类型 --> <bean id="Master" class="cn.java.di5.Master"> <constructor-arg index="0" type="java.lang.String" value="张三"></constructor-arg> <constructor-arg index="1" type="java.lang.String" value="男"></constructor-arg> </bean> <bean id="Penguin" class="cn.java.di5.Penguin"> <constructor-arg index="0" type="java.lang.String" value="Q妹"></constructor-arg> <constructor-arg index="1" type="java.lang.String" value="母"></constructor-arg> <constructor-arg index="2" type="java.lang.Integer" value="2"></constructor-arg> <constructor-arg index="3" type="cn.java.di5.Master" ref="Master"></constructor-arg> </bean>
- 通过set方法赋值
<!-- 通过set注入 --> <bean id="Person" class="cn.java.di5.Person"> <property name="personName" value="王二麻子"></property> <property name="age" value="12"></property> <property name="list"> <list> <value>list集合1</value> <value>list集合2</value> <value>20</value> <value>3.14</value> <ref bean="Master"/> </list> </property> <property name="set"> <set> <value>list集合1</value> <value>list集合2</value> <value>20</value> <value>3.14</value> <ref bean="Master"/> </set> </property> <property name="map"> <map> <entry key="1" value="王二麻子"></entry> <entry key="2" value="李四"></entry> <entry key-ref="Master" value-ref="Penguin"></entry> </map> </property> <property name="properties"> <props> <prop key="driver">com.mysql.jdbc.Driver</prop> <prop key="url">jdbc:mysql:///learnSpring</prop> </props> </property> </bean>
三. AOP——面向切面
举例:使用手机银行App实现转账、查余额等业务。本案例中目标方法是转账、查余额为业务类Work,但在实现目标方法前需要验
证环境是否安全Security、实现目标方法后需要清除操作数据ClearResource、记录日志AppLog。最后MVC架构各层代码不能混
合,所以有一个Windows类用以调用之前的方法实现最终目标。
3.1 概念
- 切面:Security、 ClearResource、 AppLog等类为切面
- 通知:切面中的方法称为通知
- 前置通知:在目标方法执行之前的通知
- 后置通知:在目标方法执行之后的通知
- 环绕通知:
- 异常通知:
- 切入点:目标方法
- 织入:将切面、通知、目标方法等一系列连接起来的过程
- 代理:Windows类
3.2 需要jar包
- aspectjrt.jar:切面
- aspectjweaver.jar:织面
- cglib-nodep.jar:代理
3.3 代码
<!-- AOP配置:以笔记中的银行举例练习 -->
<!-- 将三个切面交给spring容器来创建对象 -->
<bean id="security" class="cn.java.dao.impl.Security"></bean>
<bean id="applog" class="cn.java.dao.impl.AppLog"></bean>
<bean id="ClearResource" class="cn.java.dao.impl.ClearResource"></bean>
<!-- 将核心类交给spring容器来创建对象 -->
<bean id="appDaoImpl" class="cn.java.dao.impl.AppDaoImpl"></bean>
<!-- 开始配置AOP -->
<aop:config>
<!-- 配置切入点 -->
<!-- 第一个*号后必须有个空格 -->
<aop:pointcut expression="execution(* cn.java.dao.impl.AppDaoImpl.*(..))" id="dian"/>
<!-- 配置切面 -->
<aop:aspect ref="security">
<aop:before method="isSecurity" pointcut-ref="dian"/>
</aop:aspect>
<!-- order:用以规定执行顺序,值越大越先执行 -->
<aop:aspect ref="ClearResource" order="">
<aop:after method="clear" pointcut-ref="dian"/>
</aop:aspect>
<aop:aspect ref="applog">
<aop:after method="log" pointcut-ref="dian"/>
</aop:aspect>
</aop:config>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
AppDaoImpl app = (AppDaoImpl) context.getBean("appDaoImpl");
app.zhuanMoney();
}
3.4 环绕通知
//该参数point会被Spring提供参数,不需要人为传参
public void isLogin(ProceedingJoinPoint point) throws Throwable {
if ("admin".equals(username) && "123456".equals(password)) {
System.out.println("登录成功");
point.proceed();// 放行。放行后才能继续执行核心方法,对其他切面没影响
} else {
System.out.println("登录失败");
}
}
<!-- 配置环绕通知 -->
<aop:aspect ref="login">
<aop:around method="isLogin" pointcut-ref="dian"/>
</aop:aspect>
3.5 通过注解实现IOC
<!-- 配置包扫描和注解驱动 -->
<context:component-scan base-package="cn.java.annotation"></context:component-scan>
@Component("person")
@Scope() //指定单例与多例
public class Person{
private String username;
private String gender;
public void study(){
system.out.println("Person......study.....人可以学习");
}
}
3.6 通过注解实现DI
注解实现DI是对自定义类型进行注入
@Autowired
//@Resource(name="") 在不同包下有相同类时,可以用name指定需要的是哪个
private Person person;
3.7 其他注解
- 现在已知@Component注解是将创建对象交给Spring框架,但在实际项目中,由于严格区分MVC结构,故将这个注解拆分为以下三个:
- @Repository:修饰dao层
- @Service:修饰service层
- @Controller:修饰servlet层。一个普通类被这个注解修饰立马变成servlet
四、 Spring和Mybatis整合
需要有mybatis.xml和applicationContext.xml两个配置文件,但整合的内容(既以下代码)都写在applicationContext.xml中
从此不再写“cn.java.dao.impl”,将之替换为“cn.java.mapper”
<!-- 第一步:配置包扫描:只需要扫描service和servlet就可以 -->
<context:compont-scan back-package="cn.java.servlet,cn.java.service.impl"></context>
<!-- 第二步:配置数据源:driver、url、username、password -->
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///数据库名"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 第三步:扫描局部配置文件 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 告诉spring容器创建SqlSession对象时,连接的是哪个数据库、用户名、密码 -->
<property name="dataSource" ref="basicDataSource"></property>
<!-- 扫描的对象 -->
<property name="mapperLocations" value="cn/java/mapper/*.xml"></property>
</bean>
<!-- 第四步:将dao层中的方法与局部配置文件中的sql自动关联 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定dao层类的位置 -->
<property name="basePackage" value="cn.java.mapper"></proterty>
</bean>