目录
概要
· 2002,首次推出了Spring框架的雏形:interface21框架!
- Spring是一个开源的免费的框架(容器)!
- Spring是一个轻量级的、非入侵式的框架!
- 控制反转(IOC),面向切面编程(AOP)!
- 支持事务的处理,对框架整合的支持!
IOC
依赖倒转 - LuoTian - 博客园 (cnblogs.com)
依赖倒转原则的思想是IOC(Inversion of Control)控制反转,IOC的一种实现方法是DI(Dependency Injection)依赖注入。
Spring的配置文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用Spring 来创建对象,在Spring 中,这些都称为bean
类型 变量名 = new 类型();
User user = new User();
bean = 对象 new User();
id = 变量名
class = new 的对象;
property 相当于 给对象中的属性设置一个值!
-->
<bean id="user" class="com.whirl.User">
<property name="name" value="cestbon"/>
</bean>
</beans>
测试实现
public static void main(String[] args) {
//获取Spring 的上下文对象
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在Spring 中管理了,我们要使用,直接去里面取出来就行了
User user = (User)ac.getBean("user");
//打印
System.out.println(user.toString());
}
ClassPathXmlApplicationContext
-
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
-
反转:程序本身不创建对象,而变成被动的接收对象。
-
依赖注入:就是利用set方法来进行注入的。
-
IOC是一种编程思想,由主动的编程变成被动的接收。可以通过new ClassPathXmlApplicationContext去浏览一下底层源码。
-
到了现在,不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配!
-
IOC默认使用无参构造创建对象。
有参的使用数组下标赋值
<bean id="user" class="com.whirl.pojo.User">
<constructor-arg index="0" value="cestbon"/>
</bean>
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.whirl.Address">
<property name="address" value="gfdf"/>
</bean>
<bean id="student" class="com.whirl.Student">
<!--注入address 类型-->
<property name="address" ref="address"/>
<!--String 类型-->
<property name="name" value="234"/>
<!--String 类型-->
<property name="books">
<array>
<value>JavaSE</value>
<value>JavaWeb</value>
<value>Spring</value>
<value>SpringMVC</value>
<value>Mybatis</value>
</array>
</property>
<!--List-->
<property name="hobbies">
<list>
<value>唱</value>
<value>跳</value>
<value>rap</value>
<value>篮球</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="435" value="dasd"></entry>
<entry key="123" value="ewq"></entry>
</map>
</property>
<!--set-->
<property name="games">
<set>
<value>唱</value>
<value>跳</value>
<value>rap</value>
<value>篮球</value>
</set>
</property>
<!--String-->
<property name="wife" value="xxx"></property>
<!--Properties-->
<property name="info">
<props>
<prop key="p1">v1</prop>
<prop key="p2">v2</prop>
<prop key="p3">v3</prop>
</props>
</property>
</bean>
</beans>
Spring自动装配
ByName方法自动装配
- autowire=“byName”
- 会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
- 弊端:set 方法后面的值和 id 相同
<bean id="cat" class="cn.bloghut.domin.Cat"/>
<bean id="dog" class="cn.bloghut.domin.Dog"/>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
-->
<bean id="people" class="cn.bloghut.domin.People" autowire="byName">
<property name="name" value="csdn_闲言"/>
</bean>
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
People people = ac.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}
- autowire=“byType”
- 会自动在容器上下文中查找,和自己对象属性类型相同的bean
- 弊端:它必须保证类型全局唯一(在IOC容器中只能由一个)。
<bean id="cat" class="cn.bloghut.domin.Cat"/>
<bean id="dog11" class="cn.bloghut.domin.Dog"/>
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
-->
<bean id="people" class="cn.bloghut.domin.People" autowire="byType">
<property name="name" value="csdn_闲言"/>
</bean>
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
People people = ac.getBean("people", People.class);
people.getCat().shout();
people.getDog().shout();
}
总结:
byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
注解实现自动装配
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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.whirl"/>
<!--开启注解支持-->
<context:annotation-config/>
</beans>
@Autowired
- 在属性上使用
- 在set方式上使用
- 使用Autowired 可以不用编写set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在(需要通过其他方式注入进容器),且符合名字byName。
@Componet
等价于<bean id="user" class="cn.bloghut.domain.User">
@Configuration
本质就是一个@Componet,所以也会被Spring加载,具体看闲言博客
AOP
基于原生API
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
public class Log implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+" 的 "+method.getName()+"方法执行了");
}
}
bean.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="cn.bloghut.service.UserServiceImpl"/>
<bean id="afterLog" class="cn.bloghut.log.AfterLog"/>
<bean id="log" class="cn.bloghut.log.Log"/>
<!--方式一,使用原生的Api 接口-->
<!--配置aop-->
<aop:config>
<!--1.配置切入点 pointcut 切入点 expression 表达式, execution(要执行的位置!)-->
<!-- 切入点 在什么地方执行你的代码-->
<aop:pointcut id="pointcut" expression="execution(* cn.bloghut.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加!-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
切面方式
bean.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="cn.bloghut.service.UserServiceImpl"/>
<bean id="diyPointCut" class="cn.bloghut.diy.DiyPointCut"/>
<!--方式一,使用原生的Api 接口-->
<!--配置aop-->
<aop:config>
<!--1.配置切入点 pointcut 切入点 expression 表达式, execution(要执行的位置!)-->
<!-- 切入点 在什么地方执行你的代码-->
<aop:pointcut id="pointcut" expression="execution(* cn.bloghut.service.UserServiceImpl.*(..))"/>
<!--自定切面 ref 要引用的类-->
<aop:aspect id="aspect" ref="diyPointCut">
<!--方法执行前 method:切入的方法 pointcut:切入点 -->
<aop:before method="before" pointcut-ref="pointcut"/>
<!--方法执行后-->
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
注解方式
- 注意开启注解aop支持
<aop:aspectj-autoproxy/>
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="cn.bloghut.service.UserServiceImpl"/>
<bean id="annotationPointcut" class="cn.bloghut.annotation.AnnotationPointcut"/>
<!--开启aop 注解支持-->
<aop:aspectj-autoproxy/>
</beans>
Spring 整合Mybatis
依赖
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis 包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--spring 的 context core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--Spring操作数据库的话,还需要一个spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--Aop 支持-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.13</version>
</dependency>
<!--mybatis 整合 spring 的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!--setter 构造方法插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
数据源
<!--
DataSource:使用Spring 的数据源 替换Mybatis 的配置 c3p0 dbcp druid
使用Spring 提供的JDBC org.springframework.jdbc.datasource.
-->
<!--配置数据源-->
<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"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
2.sqlSessionFactory
<!--配置sqlSessionFactory 工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis的配置文件-->
<property name="mapperLocations" value="classpath:cn/bloghut/mapper/*Mapper.xml"/>
<!--配置别名-->
<property name="typeAliases" value="cn.bloghut.domain.User"/>
</bean>
3.sqlSessionTemplate
<!--SqlSessionTemplate 就是sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入sqlSessionFactory,因为它没有 set 方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--
DataSource:使用Spring 的数据源 替换Mybatis 的配置 c3p0 dbcp druid
使用Spring 提供的JDBC org.springframework.jdbc.datasource.
-->
<!--配置数据源-->
<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"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<!--配置sqlSessionFactory 工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis的配置文件-->
<property name="mapperLocations" value="classpath:cn/bloghut/mapper/*Mapper.xml"/>
<!--配置别名-->
<property name="typeAliases" value="cn.bloghut.domain.User"/>
</bean>
<!--SqlSessionTemplate 就是sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入sqlSessionFactory,因为它没有 set 方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!--==============================事务配置开始==============================-->
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--结合AOP 实现事务的织入-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--给哪些方法配置事务-->
<!--配置事务的传播特性:
propagation
read-only="true" 只读
-->
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="find" read-only="true"/>
<!--给所有方法配置事务-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="txPointcut" expression="execution(* cn.bloghut.mapper.*.*(..))"/>
<!--切入事务-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!--==============================事务配置结束==============================-->
</beans>
applicationContext.xml和UserMapper配置文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="cn.bloghut.mapper.impl.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bloghut.mapper.UserMapper">
<select id="findAll" resultType="cn.bloghut.domain.User">
select * from user;
</select>
<insert id="add" parameterType="cn.bloghut.domain.User">
insert into user(username,password,perms) values (#{username},#{password},#{perms})
</insert>
<delete id="delete" parameterType="int">
delete form user where id = #{value}
</delete>
</mapper>