Spring
概念
1.Spring是一个轻量级的开源的JavaEE框架
2.解决企业应用开发复杂性
3.两核心技术:IOC与AOP
4.核心jar包:(beans,core)-->IOC;context-->命名空间;expression-->表达式;comons-logging-->日志,外部依赖;
5.官网(spring.IO)下载:(repo.spring.io)-->(https://repo.spring.io/release/org/springframework/)
6.maven下载:(https://mvnrepository.com/tags/spring)
7.依赖:spring-webmvc,lombok,spring-tx(transaction),mybatis(orm),spring-jdbc,mysql-connector-java,log4j-api,
log4j-core,log4j-slf4j-impl,slf4j-api,junit,druid,spring-aop,aspectj,cglib,aspectjweaver,cglib-nodep
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 <groupId>com.wenhaosu</groupId> 7 <artifactId>spring-01</artifactId> 8 <version>1.0-SNAPSHOT</version> 9 <dependencies> 10 <dependency> 11 <groupId>org.springframework</groupId> 12 <artifactId>spring-webmvc</artifactId> 13 <version>5.2.6.RELEASE</version> 14 </dependency> 15 <dependency> 16 <groupId>org.projectlombok</groupId> 17 <artifactId>lombok</artifactId> 18 <version>1.18.12</version> 19 <scope>provided</scope> 20 </dependency> 21 <dependency> 22 <groupId>junit</groupId> 23 <artifactId>junit</artifactId> 24 <version>4.12</version> 25 </dependency> 26 <dependency> 27 <groupId>com.alibaba</groupId> 28 <artifactId>druid</artifactId> 29 <version>1.1.10</version> 30 </dependency> 31 <dependency> 32 <groupId>org.springframework</groupId> 33 <artifactId>spring-aop</artifactId> 34 <version>5.2.5.RELEASE</version> 35 </dependency> 36 <dependency> 37 <groupId>org.aspectj</groupId> 38 <artifactId>aspectjweaver</artifactId> 39 <version>1.9.5</version> 40 </dependency> 41 <dependency> 42 <groupId>cglib</groupId> 43 <artifactId>cglib-nodep</artifactId> 44 <version>2.2</version> 45 <scope>test</scope> 46 </dependency> 47 <dependency> 48 <groupId>mysql</groupId> 49 <artifactId>mysql-connector-java</artifactId> 50 <version>5.1.18</version> 51 </dependency> 52 <dependency> 53 <groupId>org.springframework</groupId> 54 <artifactId>spring-jdbc</artifactId> 55 <version>5.2.7.RELEASE</version> 56 </dependency> 57 <dependency> 58 <groupId>org.springframework</groupId> 59 <artifactId>spring-tx</artifactId> 60 <version>5.2.7.RELEASE</version> 61 </dependency> 62 <dependency> 63 <groupId>org.mybatis</groupId> 64 <artifactId>mybatis</artifactId> 65 <version>3.4.6</version> 66 </dependency> 67 <!-- log4j2的包:建议2.6以上 开始--> 68 <dependency> 69 <groupId>org.apache.logging.log4j</groupId> 70 <artifactId>log4j-api</artifactId> 71 <version>2.8.2</version> 72 </dependency> 73 <dependency> 74 <groupId>org.apache.logging.log4j</groupId> 75 <artifactId>log4j-core</artifactId> 76 <version>2.8.2</version> 77 </dependency> 78 <!-- log4j2的包:建议2.6以上 结束--> 79 <!-- log4j2和slf4j桥接依赖 --> 80 <dependency> 81 <groupId>org.apache.logging.log4j</groupId> 82 <artifactId>log4j-slf4j-impl</artifactId> 83 <version>2.8.2</version> 84 </dependency> 85 <!-- slf4j依赖 --> 86 <dependency> 87 <groupId>org.slf4j</groupId> 88 <artifactId>slf4j-api</artifactId> 89 <version>1.7.25</version> 90 </dependency> 91 </dependencies> 92 <build> 93 <resources> 94 <resource> 95 <directory>src/main/java</directory> 96 <includes> 97 <include>**/*.properties</include> 98 <include>**/*.xml</include> 99 </includes> 100 <filtering>true</filtering> 101 </resource> 102 </resources> 103 <plugins> 104 <plugin> 105 <groupId>org.apache.maven.plugins</groupId> 106 <artifactId>maven-compiler-plugin</artifactId> 107 <configuration> 108 <source>6</source> 109 <target>6</target> 110 </configuration> 111 </plugin> 112 </plugins> 113 </build> 114 </project>
步骤
1.加载Spring配置文件
new ClassPathXMLApplicationContext(".xml");//相对路径
new FileSystemXMLApplicationContext(".xml");//绝对路径
2.获取对象
context .getBean("id" , .class);
IOC
原理
1.把对象创建和对象之间的调用过程,交给spring容器管理
2.解耦
3.XML解析,工厂模式,反射
(1)工厂模式(解耦)
(2)XML解析得到Class属性值
(3)反射Class.forName(Class属性值).newInstance()创建对象(进一步解耦)
接口
BeanFactory(懒加载:加载配置文件时不会创建对象,使用对象时才创建):Spring内部使用接口
ApplicationContext(BeanFactory子接口) :开发人员使用接口
操作(XML,注解)
Bean管理:创建对象和注入属性
普通Bean
定义类型就是返回类型
工厂Bean(FactoryBean)
定义类型和返回类型可以不一样
定义类型:<bean id="user" class="com.wenhaosu.bean.MyBean">//MyBean.class
返回类型:context .getBean("id" , User.class);//User.class
Bean作用域
singleton(单例):加载Spring配置文件之后就创建对象
prototype(原型):获取对象之后创建对象
request,session
Bean生命周期
(1)创建Bean实例(构造器)
(2)为Bean属性设置和其他Bean引用(set方法)
1.ean实例传到Bean后置处理器 postProcessBeforeInitialization
(3)Bean初始化(配置)
2.Bean实例传到Bean后置处理器 postProcessAfterInitialization
(4)Bean使用(对象获取了)
(5)容器关闭,销毁Bean(配置)
有Bean后置处理器多两步
XML 方式
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:c="http://www.springframework.org/schema/c" 6 xmlns:util="http://www.springframework.org/schema/util" 7 xmlns:context="http://www.springframework.org/schema/context" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd 10 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 11 <!--p命名空间注入--> 12 <!--<bean id="user" class="com.wenhaosu.bean.User" p:name="wenhaosu"></bean>--> 13 <!--c命名空间注入--> 14 <!--<bean id="user" class="com.wenhaosu.bean.User" c:name="wenhaosu"></bean>--> 15 <bean id="user" class="com.wenhaosu.bean.User" autowire="byName"><!-- byType--> 16 <!--set方式注入--> 17 <property name="name" value="wenhaosu"></property> 18 <!--有参构造注入--> 19 <!--<constructor-arg name="name" value="wenhaosu"></constructor-arg>--> 20 <!--<constructor-arg index="0" value="wenhaosu"></constructor-arg>--> 21 <!--空值设定--> 22 <!--<property name="name"> 23 <null/> 24 </property>--> 25 <!--特殊符号设定 26 1.<>(<>) 27 2.写到cdata中--> 28 <!--<property name="name" value="<wenhaosu>"></property>--> 29 <!--<property name="name"> 30 <value><![CDATA[<<wenhaosu>>]]></value> 31 </property>--> 32 <!--外部bean--> 33 <!--<property name="dept" ref="dept"></property>--> 34 <!--内部bean--> 35 <!--<property name="dept"> 36 <bean id="dept" class="com.wenhaosu.bean.Dept"> 37 <property name="dname" value="保安部"></property> 38 </bean> 39 </property>--> 40 <!--级联赋值--> 41 <!--<property name="dept" ref="dept"></property> 42 <property name="dept.dname" value="技术部"></property>--> 43 </bean> 44 <!--外部bean--> 45 <bean id="dept" class="com.wenhaosu.bean.Dept" init-method="init" destroy-method="destroy"> 46 <property name="dname" value="财务部"></property> 47 <!--集合属性注入(数组,List,Map)--> 48 <property name="strs"> 49 <array> 50 <value>Java课程</value> 51 <value>Oracle课程</value> 52 </array> 53 </property> 54 <property name="maps"> 55 <map> 56 <entry key="Java" value="Java"></entry> 57 <entry key="Oracle" value="Oracle"></entry> 58 </map> 59 </property> 60 <property name="sets"> 61 <set> 62 <value>Java</value> 63 <value>Oracle</value> 64 </set> 65 </property> 66 <!--<property name="lists1"> 67 <list> 68 <value>Java课程</value> 69 <value>Oracle课程</value> 70 </list> 71 </property>--> 72 <!--对象类型集合注入--> 73 <!--<property name="lists2"> 74 <list> 75 <ref bean="user"></ref> 76 </list> 77 </property>--> 78 <!--公共部分抽取--> 79 <property name="lists1" ref="utilLists1"></property> 80 </bean> 81 <!--公共部分抽取--> 82 <util:list id="utilLists1"> 83 <value>util:Java课程</value> 84 <value>util:Oracle课程</value> 85 </util:list> 86 <!--FactoryBean--> 87 <bean id="myBean" class="com.wenhaosu.bean.MyBean" scope="singleton"></bean> 88 <!--Bean后置处理器(为每一个Bean添加Bean后置处理器)--> 89 <bean id="myBeanPost" class="com.wenhaosu.bean.MyBeanPost"></bean> 90 <!--<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 91 <property name="driverClassName" value="${prop.driverClass}"></property> 92 <property name="url" value="${prop.url}"></property> 93 <property name="username" value="${prop.userName}"></property> 94 <property name="password" value="${prop.password}"></property> 95 </bean>--> 96 <!--引入配置文件--> 97 <context:property-placeholder location="classpath:jdbc.properties"/> 98 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 99 <property name="driverClassName" value="${prop.driverClass}"></property> 100 <property name="url" value="${prop.url}"></property> 101 <property name="username" value="${prop.userName}"></property> 102 <property name="password" value="${prop.password}"></property> 103 </bean> 104 </beans>
1 package com.wenhaosu.bean; 2 import lombok.Data; 3 import org.springframework.beans.factory.FactoryBean; 4 @Data 5 public class MyBean implements FactoryBean { 6 private int id; 7 private String name; 8 //定义返回bean 9 public Object getObject() throws Exception { 10 User user = new User(); 11 user.setName("wenhaosu"); 12 return user; 13 } 14 // 15 public Class<?> getObjectType() { 16 return null; 17 } 18 // 19 public boolean isSingleton() { 20 return false; 21 } 22 }
1 package com.wenhaosu.bean; 2 import org.springframework.beans.BeansException; 3 import org.springframework.beans.factory.config.BeanPostProcessor; 4 public class MyBeanPost implements BeanPostProcessor { 5 @Override 6 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 7 System.out.println("初始化之前"); 8 return bean; 9 } 10 @Override 11 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 12 System.out.println("初始化之后"); 13 return bean; 14 } 15 }
1 package com.wenhaosu.bean; 2 import lombok.Data; 3 @Data 4 public class User { 5 private int id; 6 private String name; 7 private int money; 8 private Dept dept;//byType通过类型com.wenhaosu.bean.Dept自动注入(如果配置文件中有两个Dept的bean时出错);byName过名称dept自动注入; 9 @Override 10 public String toString() { 11 return "User{" + 12 "id=" + id + 13 ", name='" + name + '\'' + 14 ", dept=" + dept + 15 '}'; 16 } 17 }
1 package com.wenhaosu.bean; 2 import lombok.Data; 3 import java.util.Arrays; 4 import java.util.List; 5 import java.util.Map; 6 import java.util.Set; 7 @Data 8 public class Dept { 9 private int deptno; 10 private String dname; 11 private List<User> users; 12 private String[] strs; 13 private List<String> lists1; 14 private List<User> lists2; 15 private Map<String,Object> maps; 16 private Set<String> sets; 17 public Dept(){ 18 System.out.println("(1)无参构造"); 19 } 20 @Override 21 public String toString() { 22 return "Dept{" + 23 "deptno=" + deptno + 24 ", dname='" + dname + '\'' + 25 ", users=" + users + 26 ", strs=" + Arrays.toString(strs) + 27 ", lists1=" + lists1 + 28 ", lists2=" + lists2 + 29 ", maps=" + maps + 30 ", sets=" + sets + 31 '}'; 32 } 33 public void setDname(String dname) { 34 System.out.println("(2)set属性值"); 35 this.dname = dname; 36 } 37 public void init(){ 38 System.out.println("(3)初始化"); 39 } 40 public void destroy(){ 41 System.out.println("(5)销毁"); 42 } 43 }
1 public class test { 2 @Test 3 public void test01(){//外部bean,内部bean,级联,自动装配autowire 4 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 5 User user1 = context.getBean("user", User.class); 6 User user2 = context.getBean("user", User.class); 7 System.out.println(user1==user2);//默认是singleton 8 user1.setId(1); 9 System.out.println(user1.toString()); 10 } 11 @Test 12 public void test02(){//工厂bean 13 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 14 User user1 = context.getBean("myBean", User.class); 15 User user2 = context.getBean("myBean", User.class); 16 System.out.println(user1==user2);//无论是singleton还是prototype都是false 17 System.out.println(user1.getName()); 18 } 19 @Test 20 public void test03(){//Bean生命周期,lists2 21 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 22 System.out.println("(4)获取到Bean对象"); 23 Dept dept = context.getBean("dept", Dept.class); 24 System.out.println(dept.toString()); 25 ((ClassPathXmlApplicationContext)context).close();//销毁方法在ClassPathXmlApplicationContext中的 26 } 27 }
注解 方式
对象创建(功能一样):
@Component
@Service
@Controller
@Repository
没有设置value值时默认全名称首字母小写
属性注入:
@AutoWired:属性类型
@Qualifier:属性名称
@Resource:属性类型,名称
@Value:注入普通类型属性
1 package com.wenhaosu.Controller; 2 import com.wenhaosu.Service.UserService; 3 import com.wenhaosu.bean.User; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.beans.factory.annotation.Qualifier; 6 import org.springframework.stereotype.Controller; 7 import java.util.List; 8 @Controller 9 public class UserController { 10 @Autowired 11 @Qualifier(value="userServiceImpl") 12 private UserService userService; 13 public void add(User user){ 14 System.out.println("controller add......"); 15 userService.add(user); 16 } 17 public List<User> queryUser(){ 18 System.out.println("controller query......"); 19 userService.queryUser(); 20 return userService.queryUser(); 21 } 22 public void batchAdd(List<Object[]> users){ 23 userService.batchAdd(users); 24 } 25 public void tranferAccount() { 26 userService.tranferAccount(); 27 } 28 }
1 package com.wenhaosu.Service.Impl; 2 import com.wenhaosu.Mapper.UserMapper; 3 import com.wenhaosu.Service.UserService; 4 import com.wenhaosu.bean.User; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.beans.factory.annotation.Qualifier; 7 import org.springframework.beans.factory.annotation.Value; 8 import org.springframework.stereotype.Service; 9 import org.springframework.transaction.annotation.Isolation; 10 import org.springframework.transaction.annotation.Propagation; 11 import org.springframework.transaction.annotation.Transactional; 12 import javax.annotation.Resource; 13 import java.util.List; 14 /* 15 propagation 事务传播行为(有无事务的方法相互调用) 16 required 有事务就调用,没有就创建,并运行在自己的事务中 17 required_new 是否有事务都创建新事务 18 19 ioslation 事务隔离级别 20 read uncommitted(读未提交)YYY 21 read committed(读已提交)NYY(Oracle默认) 22 repeatable read(可重复读)NNY(Mysql默认) 23 serializable(序列化)NNN 24 隔离性(脏读,不可重复读,幻读) 25 1.脏读:一个未提交事务读取到另一个未提交事务的数据(回滚问题) 26 2.不可重复读:一个未提交事务读取到另一个提交事务修改的数据(行) 27 3.幻读:一个未提交事务读取到另一个提交事务添加的数据(表) 28 29 timeout 超时时间(一定时间内提交,超时不提交回滚,秒为单位,默认-1) 30 readOnly 是否只读(默认false,为true时只能查询) 31 rollbackFor 回滚(出现哪些异常时事务回滚) 32 noRollbackFor 不回滚(出现哪些异常时事务不回滚) 33 */ 34 /* 35 @Component(value="userService") 36 value可以不写,默认是类名:UserServiceImpl首字母小写 37 */ 38 @Service 39 @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ) 40 public class UserServiceImpl implements UserService { 41 //不需要set方法 42 //@Resource//类型注入(多个接口实现类就不行了) 43 //@Resource(name="UserMapperImpl")//名称注入 44 @Autowired//类型注入(多个接口实现类就不行了) 45 @Qualifier(value = "userMapperImpl")//名称注入 46 private UserMapper userMapper; 47 @Value(value = "wenhaosu")//普通属性注入 48 private String name; 49 @Override 50 public void add(User user){ 51 System.out.println("service add......"); 52 userMapper.add(user); 53 System.out.println(getName()); 54 } 55 public List<User> queryUser(){ 56 System.out.println("service query......"); 57 List<User> users = userMapper.queryUser(); 58 System.out.println(getName()); 59 return users; 60 } 61 public void batchAdd(List<Object[]> users){ 62 userMapper.batchAdd(users); 63 } 64 @Override 65 public void tranferAccount() { 66 userMapper.transaction1(); 67 int a = 10/0; 68 userMapper.transaction2(); 69 } 70 public String getName() { 71 return name; 72 } 73 }
1 package com.wenhaosu.Mapper; 2 import com.wenhaosu.bean.User; 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Qualifier; 5 import org.springframework.jdbc.core.BeanPropertyRowMapper; 6 import org.springframework.jdbc.core.JdbcTemplate; 7 import org.springframework.stereotype.Repository; 8 import java.util.Arrays; 9 import java.util.List; 10 @Repository 11 public class UserMapperImpl implements UserMapper{ 12 @Autowired 13 //@Qualifier(value="jdbcTemplate") 14 private JdbcTemplate jdbcTemplate; 15 public void add(User user){ 16 System.out.println("Mapper add......"); 17 String sql = "insert into emp values(?,?,?)"; 18 Object[] args = {user.getId(),user.getName(),user.getDept().getDeptno()}; 19 int add = jdbcTemplate.update(sql,args); 20 System.out.println(add); 21 } 22 public List<User> queryUser(){ 23 String sql = "select empno as id,name from emp"; 24 //jdbcTemplate.queryForObject(sql,List.class);//返回单个值 25 //jdbcTemplate.queryForObject( sql, new Object[]{}, new BeanPropertyRowMapper<User>(User.class));//返回对象 26 List<User> users =jdbcTemplate.query( sql, new Object[]{}, new BeanPropertyRowMapper<User>(User.class));//返回集合 27 return users; 28 } 29 public void batchAdd(List<Object[]> users) { 30 String sql = "insert into emp values(?,?,?)"; 31 int[] add = jdbcTemplate.batchUpdate(sql,users); 32 System.out.println(Arrays.toString(add)); 33 } 34 @Override 35 public void transaction1() { 36 String sql = "update t_user set money = money-? where name=?"; 37 int update = jdbcTemplate.update(sql,100,"lucy"); 38 } 39 @Override 40 public void transaction2() { 41 String sql = "update t_user set money = money+? where name=?"; 42 int update = jdbcTemplate.update(sql,100,"mary"); 43 } 44 }
1 package com.wenhaosu.Service; 2 import com.wenhaosu.bean.User; 3 import java.util.List; 4 public interface UserService { 5 public void add(User user); 6 public List<User> queryUser(); 7 public void batchAdd(List<Object[]> users); 8 public void tranferAccount(); 9 }
1 package com.wenhaosu.Mapper; 2 import com.wenhaosu.bean.User; 3 import java.util.List; 4 public interface UserMapper { 5 public void add(User user); 6 public List<User> queryUser(); 7 public void batchAdd(List<Object[]> users); 8 public void transaction1(); 9 public void transaction2(); 10 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 11 12 <!--扫描包--> 13 <!--<context:component-scan base-package="com.wenhaosu.Mapper,com.wenhaosu.Service,com.wenhaosu.Controller"/>--> 14 <context:component-scan base-package="com.wenhaosu"/> 15 <!--只扫描annotation中的Service注解;不扫描Controller注解--> 16 <!--<context:component-scan base-package="com.wenhaosu"> 17 <context:include-filter type="annotation" 18 expression="org.springframework.stereotype.Service"/> 19 <context:exclude-filter type="annotation" 20 expression="org.springframework.stereotype.Controller"/> 21 </context:component-scan>--> 22 <context:property-placeholder location="classpath:jdbc.properties"/> 23 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 24 <property name="driverClassName" value="${prop.driverClass}"></property> 25 <property name="url" value="${prop.url}"></property> 26 <property name="username" value="${prop.userName}"></property> 27 <property name="password" value="${prop.password}"></property> 28 </bean> 29 <!--JdbcTemplate对象--> 30 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 31 <!--注入数据源--> 32 <property name="dataSource" ref="dataSource"></property> 33 </bean> 34 <!--事务管理器--> 35 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 36 <!--注入数据源--> 37 <property name="dataSource" ref="dataSource"></property> 38 </bean> 39 <!--事务注解方式--> 40 <!--开启事务注解 proxy-target-class="true"表示基于cglib代理--> 41 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"></tx:annotation-driven> 42 <!-- AspectJ注解方式 --> 43 <!-- 扫描包 --> 44 <!--<context:component-scan base-package="com.wenhaosu"></context:component-scan>--> 45 <!--开启AspectJ注解 生成代理对象--> 46 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 47 </beans>
1 public class test { 2 @Test 3 public void test04(){//注解 4 //XML文件 5 //ApplicationContext context = new ClassPathXmlApplicationContext("spring2.xml"); 6 //UserService userService = context.getBean("userServiceImpl", UserServiceImpl.class);//注解的value值:UserServiceImpl 7 //System.out.println(userService); 8 //Configuration代替XML文件 9 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); 10 UserService userService = context.getBean("userServiceImpl", UserServiceImpl.class);//注解的value值:userController 11 System.out.println(userService); 12 13 User user = new User(); 14 user.setId(1); 15 user.setName("wenhaosu"); 16 Dept dept = new Dept(); 17 dept.setDeptno(1); 18 user.setDept(dept); 19 userService.add(user); 20 } 21 @Test 22 public void test05() {//AspectJ 23 //注解 24 ApplicationContext context = new ClassPathXmlApplicationContext("spring2.xml"); 25 User2 user2 = context.getBean("user2",User2.class); 26 user2.add(); 27 //XML 28 //ApplicationContext context = new ClassPathXmlApplicationContext("spring3.xml"); 29 //Book book = context.getBean("book",Book.class); 30 //book.add(); 31 } 32 @Test 33 public void test06() {//Jdbc 34 ApplicationContext context = new ClassPathXmlApplicationContext("spring2.xml"); 35 UserController userController = context.getBean("userController", UserController.class); 36 User user = new User(); 37 user.setId(2); 38 user.setName("wenhao"); 39 Dept dept = new Dept(); 40 dept.setDeptno(1); 41 dept.setDname("财务部"); 42 user.setDept(dept); 43 userController.add(user); 44 List<User> users = userController.queryUser(); 45 System.out.println(users); 46 List<Object[]> userList = new ArrayList<Object[]>(); 47 Object[] o1 = {"1","wenhaosu","1"}; 48 Object[] o2 = {"1","suwenhao","1"}; 49 userList.add(o1); 50 userList.add(o2); 51 userController.batchAdd(userList);//批量新增 52 userController.tranferAccount(); 53 } 54 }
1 package com.wenhaosu.Config; 2 import com.alibaba.druid.pool.DruidDataSource; 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.ComponentScan; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.EnableAspectJAutoProxy; 7 import org.springframework.jdbc.core.JdbcTemplate; 8 import org.springframework.jdbc.datasource.DataSourceTransactionManager; 9 import org.springframework.transaction.annotation.EnableTransactionManagement; 10 import javax.sql.DataSource; 11 //注解类代替XML文件 12 @Configuration 13 @ComponentScan(basePackages = "com.wenhaosu")//扫描包 14 @EnableTransactionManagement(proxyTargetClass = true)//开启事务注解 15 @EnableAspectJAutoProxy//开启AspectJ注解 生成代理对象 16 public class SpringConfig { 17 //创建数据库连接池 18 @Bean 19 public DruidDataSource getDruidDataSource(){ 20 DruidDataSource dataSource = new DruidDataSource(); 21 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 22 dataSource.setUrl("jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8&useSSL=true"); 23 dataSource.setUsername("root"); 24 dataSource.setPassword("root"); 25 return dataSource; 26 } 27 //创建JdbcTemplate 28 @Bean 29 public JdbcTemplate getjdbcTemplate(DataSource dataSource){ 30 //到IOC容器中通过类型找到dataSource 31 JdbcTemplate jdbcTemplate = new JdbcTemplate(); 32 //注入dataSource 33 jdbcTemplate.setDataSource(dataSource); 34 return jdbcTemplate; 35 } 36 //创建事务管理器 37 @Bean 38 public DataSourceTransactionManager getdataSourceTransactionManager(DataSource dataSource){ 39 DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); 40 transactionManager.setDataSource(dataSource); 41 return transactionManager; 42 } 43 }
AOP
原理
面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP(面向对象编程)的延续。
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,動態添加功能:日誌,安全,事務等。
1.通知(Advice):安全,事务,日志等功能
2.连接点(JoinPoint):spring允许你使用通知的地方
3.切入点(Pointcut):切点来筛选连接点,选中那几个你想要的方法
4.切面(Aspect):切面是通知和切入点的结合
5.引入(introduction):把切面用到目標方法
6.目标(target):目标类,也就是要被通知的对象,也就是真正的业务逻辑
7.代理(proxy):代理
8.织入(weaving):把切面应用到目标对象来创建新的代理对象的过程
操作
AspectJ和Spring框架一起使用进行AOP操作
切入点表达式:execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
.. 表示所有参数,如 (..)
* 表示所有权限修饰符或类或方法
举例:execution(* com.wenhaosu.Mapper.*.* (..))
AspectJ 注解方式:
1 package com.wenhaosu.AOPAnno; 2 import org.aspectj.lang.ProceedingJoinPoint; 3 import org.aspectj.lang.annotation.*; 4 import org.springframework.stereotype.Component; 5 //增强类 6 @Component 7 @Aspect//生成代理对象 8 public class UserProxy { 9 @Before(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 10 public void before(){ 11 System.out.println("before......"); 12 } 13 //最终通知 14 @After(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 15 public void after(){ 16 System.out.println("after......"); 17 } 18 @AfterThrowing(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 19 public void afterThrowing(){ 20 System.out.println("AfterThrowing......"); 21 } 22 @Around(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 23 public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ 24 System.out.println("around之前......"); 25 proceedingJoinPoint.proceed(); 26 System.out.println("around之后......"); 27 } 28 //后置通知(返回通知) 29 @AfterReturning(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 30 public void afterReturning(){ 31 System.out.println("afterReturning......"); 32 } 33 }
1 package com.wenhaosu.AOPAnno; 2 import org.springframework.stereotype.Component; 3 //被增强类 4 @Component 5 public class User2 { 6 public void add(){ 7 System.out.println("add......."); 8 } 9 }
1 public class test { 2 @Test 3 public void test07() {//AspectJ 4 //注解 5 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 6 User2 user2 = context.getBean("user2",User2.class); 7 user2.add(); 8 //XML 9 10 } 11 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 8 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 <!-- AspectJ注解 --> 10 <context:component-scan base-package="com.wenhaosu.AOPAnno"></context:component-scan> 11 <!--开启AspectJ生成代理对象--> 12 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 13 </beans>
注意:
(1)公共部分抽取 @Pointcut
1 //增强类 2 @Component 3 @Aspect//生成代理对象 4 public class UserProxy { 5 @Pointcut(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 6 public void pointcut(){ 7 8 } 9 @Before(value = "pointcut()") 10 public void before(){ 11 System.out.println("before......"); 12 } 13 }
(2)增强类优先级 PersonProxy
1 //增强类 2 @Component 3 @Aspect//生成代理对象 4 @Order(1)//数越小,优先级越高 5 public class PersonProxy { 6 @Pointcut(value = "execution(* com.wenhaosu.AOPAnno.User2.add(..))") 7 public void pointcut(){ 8 9 } 10 @Before(value = "pointcut()") 11 public void before(){ 12 System.out.println("person before......"); 13 } 14 }
正常输出:
有异常时输出:int a = 100/0;
AspectJ XML文件方式:
1 <!-- AspectJ配置文件 --> 2 <!--创建对象--> 3 <bean id="book" class="com.wenhaosu.AOPXML.Book"></bean> 4 <bean id="bookProxy" class="com.wenhaosu.AOPXML.BookProxy"></bean> 5 <!--配置AOP增强--> 6 <!--创建对象--> 7 <aop:config> 8 <!--切入点--> 9 <aop:pointcut id="p" expression="execution(* com.wenhaosu.AOPXML.Book.add(..))"/> 10 <!--配置切面--> 11 <aop:aspect ref="bookProxy"> 12 <!--通知+切入点--> 13 <aop:before method="before" pointcut-ref="p"/> 14 </aop:aspect> 15 </aop:config>
1 package com.wenhaosu.AOPXML; 2 public class Book { 3 public void add(){ 4 System.out.println("add......"); 5 } 6 }
1 package com.wenhaosu.AOPXML; 2 import org.aspectj.lang.annotation.Before; 3 public class BookProxy { 4 //@Before(value = "execution(* com.wenhaosu.AOPXML.Book.add(..))") 5 public void before(){ 6 System.out.println("before......"); 7 } 8 }
JDBCTemplate
//新增,修改,删除 //参数1:String sql 参数2:? Object[] args = {user.getId(),user.getName(),user.getDept().getDeptno()}; int flag = jdbcTemplate.update(sql,args);
//参数1:String sql 参数2:基本类型或包装类 jdbcTemplate.queryForObject(sql,Integer.class);//返回单个值
//参数1:String sql 参数2:? 参数3:对象类型 //Object[] args = {1,"wenhaosu"}; jdbcTemplate.queryForObject( sql, new Object[]{}, new BeanPropertyRowMapper<User>(User.class));//返回对象
//参数1:String sql 参数2:? 参数3:对象类型 //Object[] args = {1,"wenhaosu"}; List<User> users =jdbcTemplate.query( sql, new Object[]{}, new BeanPropertyRowMapper<User>(User.class));//返回集合
//参数1:String sql 参数2:List<Object[]> users //List<Object[]> userList = new ArrayList<Object[]>(); //Object[] o1 = {"1","wenhaosu"}; //Object[] o2 = {"1","suwenhao"}; //userList.add(o1); //userList.add(o2); int[] flag= jdbcTemplate.batchUpdate(sql,users);//批量新增,修改,删除 System.out.println(Arrays.toString(flag));//[1,1]
事务管理
接口:事务管理器,有多个实现类,JdbcTemplate模板(Mybatis)使用DataSourceTransactionManager这个接口实现类。
编程式事务管理
声明式事务管理
事务注解方式:
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
propagation 事务传播行为(有无事务的方法相互调用)
required 有事务就调用,没有就创建,并运行在自己的事务中
required_new 是否有事务都创建新事务
ioslation 事务隔离级别
read uncommitted(读未提交)YYY
read committed(读已提交)NYY(Oracle默认)
repeatable read(可重复读)NNY(Mysql默认)
serializable(序列化)NNN
隔离性(脏读,不可重复读,幻读)
1.脏读:一个未提交事务读取到另一个未提交事务的数据(回滚问题)
2.不可重复读:一个未提交事务读取到另一个提交事务修改的数据(行)
3.幻读:一个未提交事务读取到另一个提交事务添加的数据(表)
timeout 超时时间(一定时间内提交,超时不提交回滚,秒为单位,默认-1)
readOnly 是否只读(默认false,为true时只能查询)
rollbackFor 回滚(出现哪些异常时事务回滚)
noRollbackFor 不回滚(出现哪些异常时事务不回滚)
举例:@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)//传播行为:required,隔离级别:repeatable read
一般用在service层(业务处理层),可加在方法或类上
事务XML文件方式:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 11 <!--XML方式(AOP)--> 12 <!--配置通知--> 13 <tx:advice id="txadvice"> 14 <!--配置事务参数--> 15 <tx:attributes> 16 <!--指定在哪种规则的方法上添加事务--> 17 <tx:method name="tranferAccount" propagation="REQUIRED"/> 18 <!--<tx:method name="tranfer*"/>--> 19 </tx:attributes> 20 </tx:advice> 21 <!--配置切入点和切面--> 22 <aop:config> 23 <!--切入点--> 24 <aop:pointcut id="pt" expression="execution(* com.wenhaosu.Service.UserService.tranferAccount())"/> 25 <!--配置切面--> 26 <aop:advisor advice-ref="txadvice" pointcut-ref="pt"></aop:advisor> 27 </aop:config> 28 </beans>
Spring5
1.Log4j2
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="trace"> 3 <!-- 配置日志信息输出目的地 --> 4 <Appenders> 5 <!-- 输出到控制台 --> 6 <Console name="Console" target="SYSTEM_OUT"> 7 <!--配置日志信息的格式 --> 8 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> 9 </Console> 10 <!-- 输出到文件,其中有一个append属性,默认为true,即不清空该文件原来的信息,采用添加的方式,若设为false,则会先清空原来的信息,再添加 --> 11 <File name="MyFile" fileName="E:/Log/Log4j2.log" append="false"> 12 <PatternLayout> 13 <!--配置日志信息的格式 --> 14 <pattern>%d %p %C{1.} [%t] %m%n</pattern> 15 </PatternLayout> 16 </File> 17 </Appenders> 18 <!-- 定义logger,只有定义了logger并引入了appender,appender才会有效 --> 19 <Loggers> 20 <Root level="info"> 21 <AppenderRef ref="Console"/> 22 <AppenderRef ref="MyFile"/> 23 </Root> 24 </Loggers> 25 </Configuration>
1 package com.wenhaosu.Debug; 2 import org.slf4j.Logger; 3 import org.slf4j.LoggerFactory; 4 public class Log { 5 private static final Logger log = LoggerFactory.getLogger(Log.class); 6 public static void main(String[] args) { 7 log.info("log4j2 info"); 8 log.warn("log4j2 warn"); 9 } 10 }
2.@Nullable:用在属性,方法,参数上面,可以为null