目录
【4】创建Spring的配置文件application.xml
1、什么是框架?
2、Spring是什么?
官网:Spring | Home
3、Spring的优势?
4、创建Hello World项目(两种方式)
4.1、官网创建
地址:春季|春季快速入门指南 (spring.io)
4.2、本地创建(IDEA)
【1】创建maven工程
【2】 完成后
5、Spring核心之IoC控制反转
【1】创建一个实体类
public class Team {
private Integer id;
private String name;
private String location;
public Team() {
System.out.println("Tesm-->默认构造方法 id="+id+",name="+name+",location="+location);
}
}
【2】创建一个测试类,以前
现在:
@Test
public void test01(){
//Team team = new Team();以前的
//使用spring容器创建对象
String springConfig="application.xml";
//2--->BeanFactory beanFactory =new XmlBeanFactory(new )
//3-->
ApplicationContext appletContext = new ClassPathXmlApplicationContext(springConfig);
//4-->applicationContext.getBean
Team team1= (Team) appletContext.getBean("team1");
}
【3】添加依赖
<!--
junit:代表测试@test注解
-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
</plugins>
</build>
【4】创建Spring的配置文件application.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
创建对象:
声明bean,通知spring要创建哪个类的对象
一个bean标签声明一个对象:
id="自定义的对象名称" ,
要求唯一 class="类的完全限定名" 包名+类名
spring底层是反射机制创建对象,所以必须使用类名
相当于 Team team1=new Team();
创建好的对象放入一个集合Map中
例如:springMap.put("team1",new Team()); -->
<bean id="team1" class="com.qinluyu.pojo.Team"></bean>
</beans>
【5】创建非自定义对象(获取时间)
Date date1 = (Date) applicationContext.getBean("date1");
System.out.println("自定义对象调用"+date1);
<bean id="date1" class="java.util.Date"></bean>
6、Spring容器创建对象的方式
【1】使用默认的构造方法
public Team() {
System.out.println("Team-->默认构造方法 id="+id+",name="+name+",location="+location);
}
<bean id="team1" class="com.qinluyu.pojo.Team"></bean>
【2】使用带参数的构造方法
public Team(Integer id, String name, String location) {
this.id = id;
this.name = name;
this.location = location;
System.out.println("Team-->带参数构造方法 id="+id+",name="+name+",location="+location);
}
@Test
public void test02(){
String springConfig="application.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfig);
}
【3】使用工厂类
<!--通过工厂方法:实例方法,静态方法 1、静态方法-->
<bean id="staticTeam" class="com.qinluyu.pojo.MyFactory" factory-method="staticFun"></bean>
<!--实例方法-->
<bean id="factory" class="com.qinluyu.pojo.MyFactory"></bean>
<bean id="instanceTeam" factory-bean="factory" factory-method="instanceFun"></bean>
//实例方法
public Team instanceFun(){
return new Team(1002,"李四","李四组");
}
//静态方法
public static Team staticFun(){
return new Team(1003,"李四1","李四组1");
}
public static void main(String[] args) {
MyFactory factory=new MyFactory();
Team team = factory.instanceFun();
Team team1 = MyFactory.staticFun();
}
@Test
public void test03(){
String springConfig="application.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfig);
}
7、基于XML的DI
8、基于注解实现IoC
【1】声明Bean的注解 @Component
//@Component 不指定 value 属性,bean 的 id 是类名的首字母小写。
@Component
//@Component("teamDao")
//=@Component(value = "teamDao")
//=<bean id="teaDao" class="com.qinluyu.pojo.TeamDao"></bean>
【2】例子
实体
public TeamDao(){
System.out.println("TeamDao-----------默认的构造方法");
}
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"
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">
<context:component-scan base-package="com.qinluyu.pojo"></context:component-scan>
</beans>
测试:
public void test03(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation.xml");
}
【3】其他
【4】包扫描
<context:component-scan base-package="com.qinluyu.pojo"></context:component-scan>
【5】属性注入@Vaule
实体
@Component
public class Team {
@Value("1004")
private Integer id;
@Value("王五")
private String name;
@Value("王五1")
private String location;
@Override
public String toString() {
return "Team{" +
"id=" + id +
", name='" + name + '\'' +
", location='" + location + '\'' +
'}';
}
或者
public Integer getId() {
return id;
}
@Value("1004")
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
@Value("王五")
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
@Value("王五1")
public void setLocation(String location) {
this.location = location;
}
测试
@Test
public void test04(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation.xml");
Team team = (Team) applicationContext.getBean("team");
System.out.println(team);
}
【6】@Autowired
【7】@Autowired和@Qualifier
【8】@Resource
9、Spring核心之AOP
【1】什么是AOP?
【2】什么是代理模式?
【3】静态代理
基于类的静态代理
/**
* 基于类的静态代理,每次只能代理一个类
*/
public class staticproxy extends TeamService{
public void add(){
try {
System.out.println("开始事务");
super.add();
System.out.println("提交事务");
} catch (Exception e) {
System.out.println("回滚事务");
}
}
}
基于接口的静态代理
接口
public interface IService {
void add();
}
package com.qinluyu;
public class ProxyLogService implements IService{
private IService service;//被代理的对象
public ProxyLogService(IService service) {
this.service = service;
}
@Override
public void add() {
try {
System.out.println("开始日志");
service.add();
System.out.println("提交日志");
} catch (Exception exception) {
System.out.println("回滚日志");
}
}
}
public class TeamService implements IService{
@Override
public void add(){
System.out.println("TeamService---- add----");// 核心业务
}
}
【4】动态代理
【5】基于JDK的动态代理
package com.qinluyu;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyJDKProxy {
public static void main(String[] args) {
final TeamService teamService = new TeamService();
IService proxyService = (IService) Proxy.newProxyInstance(
teamService.getClass().getClassLoader(),
teamService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
System.out.println("开始事务");
Object invoke = method.invoke(teamService, args);
System.out.println("提交事务");
return invoke;
} catch (Exception e) {
System.out.println("回滚事务");
e.printStackTrace();
throw e;
} finally {
System.out.println("----");
}
}
}
);
//代理对象干活
proxyService.add();
System.out.println(teamService.getClass());
System.out.println(proxyService.getClass()+"--------");
}
}
【6】基于CGLIB的动态代理
public static void main(String[] args) {
//目标对象:没有接口
NBAService nbaService=new NBAService();
//创建切面
AOP tranAop=new TranAOP();
//创建代理对象:选择cglib动态代理
NBAService proxyInstance = (NBAService) new CglibProxyFactory().getProxyInstance(nbaService, tranAop);
int res=proxyInstance.add("huren",1001);
System.out.println(res);
}
public static void main1(String[] args) {
//目标对象:没有接口
NBAService nbaService=new NBAService();
//创建代理对象:选择cglib动态代理
NBAService proxyService= (NBAService) Enhancer.create(nbaService.getClass(),
new MethodInterceptor() {//回调函数编写代理规则
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
try {
System.out.println("开始事务");
Object invoke = methodProxy.invokeSuper(o, objects);//核心
System.out.println("提交事务");
return invoke;
}catch (Exception e){
System.out.println("事务回滚");
throw e;
}finally {
System.out.println("finally------------");
}
}
});
int res=proxyService.add("huren",1001);
System.out.println(res);
}
10、SpringAOP
【1】AspectJ 对 AOP 的实现
【2】AspectJ的通知类型
【3】注解方式实现AOP
TeamService
@Service
public class TeamService implements IService{
@Override
public void add(int id, String name) {
//int num=10/0;
System.out.println("TeamService---- add----");
}
@Override
public boolean update(int num) {
System.out.println("TeamService---- update----");
if(num>666){
return true;
}
return false;
}
IService:
public interface IService {
void add(int id,String name);
boolean update(int num);
}
【4】前置通知
@Before("pointCut()")
public void before(JoinPoint jp){
System.out.println("前置通知:在目标方法执行之前被调用的通知");
String name = jp.getSignature().getName();
System.out.println("拦截的方法名称:"+name);
Object[] args = jp.getArgs();
System.out.println("方法的参数格式:"+args.length);
System.out.println("方法参数列表:");
for (Object arg : args) {
System.out.println("\t"+arg);
}
}
【5】后置通知
@AfterReturning(value = "pointCut2()",returning = "result")
public Object afterReturn(Object result){
if(result!=null){
boolean res=(boolean)result;
if(res){
result=false;
}
}
System.out.println("后置通知:在目标方法执行之后被调用的通知,result="+result);
return result;
}
【6】环绕通知
@Around(value = "pointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕方法---目标方法的执行之前");
Object proceed = pjp.proceed();
System.out.println("环绕方法---目标方法的执行之后");
return proceed;
}
【7】最终通知
@After( "pointCut()")
public void myFinally(){
System.out.println("最终通知:无论是否出现异常都是最后被调用的通知");
}
【8】异常通知
@AfterThrowing(value = "pointCut()",throwing = "ex")
public void exception(JoinPoint jp,Throwable ex){
//一般会把异常发生的时间、位置、原有都记录下来
System.out.println("异常通知:在目标方法执行出现异常的时候才会别调用的通知,否则不执行");
System.out.println(jp.getSignature()+"方法出现异常,异常信息是:"+ex.getMessage());
}
【9】XML方式实现AOP
/**
* 切面类
*/
@Component //切面对象的创建权限依然交给spring容器
@Aspect //aspectj 框架的注解 标识当前类是一个切面类
public class MyAOP {
public void before(JoinPoint jp){
System.out.println("AOP前置通知:在目标方法执行之前被调用的通知");
}
public void afterReturn(Object result){
System.out.println("AOP后置通知:在目标方法执行之后被调用的通知,result="+result);
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AOP环绕方法---目标方法的执行之前");
Object proceed = pjp.proceed();
System.out.println("AOP环绕方法---目标方法的执行之后");
return proceed;
}
public void exception(JoinPoint jp,Throwable ex){
//一般会把异常发生的时间、位置、原有都记录下来
System.out.println("AOP异常通知:在目标方法执行出现异常的时候才会别调用的通知,否则不执行");
System.out.println(jp.getSignature()+"方法出现异常,异常信息是:"+ex.getMessage());
}
public void myFinally(){
System.out.println("AOP最终通知:无论是否出现异常都是最后被调用的通知");
}
}
<!--xml方式实现AOP-->
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.qinluyu.service..*.*(..))"/>
<aop:pointcut id="pt2" expression="execution(* com.qinluyu.service..*.add*(..))"/>
<aop:aspect ref="myAOP">
<!--前置通知-->
<aop:before method="before" pointcut-ref="pt1"></aop:before>
<!--后置通知-->
<aop:after-returning method="afterReturn" pointcut-ref="pt2" returning="result"></aop:after-returning>
<!--环绕通知-->
<aop:around method="around" pointcut-ref="pt2"></aop:around>
<!--异常通知-->
<aop:after-throwing method="exception" pointcut-ref="pt1" throwing="ex"></aop:after-throwing>
<!--最终通知-->
<aop:after method="myFinally" pointcut-ref="pt1"></aop:after>
</aop:aspect>
</aop:config>
11、Spring整合JDBC
依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
测试
package com.qinluyu.test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
public class Test01 {
@Test
public void test01() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false");
dataSource.setUser("root");
dataSource.setPassword("123");
//使用JDBCTemplete
JdbcTemplate template = new JdbcTemplate(dataSource);
String sql = "insert into team(teamName,location) value(?,?)";
int update = template.update(sql,"zhangsan","123");
System.out.println("数据"+update);
}
}