一、Spring有两种Bean,一种是普通Bean,另外一种是工厂Bean
1.普通Bean
定义与返回类型相同
2、工厂Bean
定义与返回类型可以不同
类实现FactoryBean接口
get方法定义返回Bean类型
输出改为返回类型
二、Bean的作用域
1、设置创建Bean实例是单实例还是多实例。
2、在Spring里面,默认情况下,Bean是单实例对象。
对象地址相同,是单实例对象
3.设置单实例或多实例
scope标签:第一个值,默认值,singleton,表示单实例对象
在加载配置文件时就会创建单实例对象
第二个值:prototype,表示多实例对象
不是在加载配置文件时创建多实例对象,在获取对象getBean()时才会创建。
当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例
request
session
三、Bean的生命周期
1.什么是生命周期
(1)从对象从创建到对象销毁的过程。
2.Bean生命周期:
(1)通过构造器创建bean实例(无参构造)
(2)为Bean的属性设置值和对其他bean的引用(调用set方法)
(3)调用bean的初始化的方法(需要进行配置)
(4)bean可以使用(对象获取到了)
(5)当容器关闭,调用bean的销毁的方法。
3.bean的后置处理器,生命周期有七步
(1)通过构造器创建bean实例(无参构造)
(2)为Bean的属性设置值和对其他bean的引用(调用set方法)
(3)把bean的实例传递bean后置处理器的方法
(4)调用bean的初始化的方法(需要进行配置)
(5)把bean实例传递给bean后置处理器的方法。
(6)bean可以使用(对象获取到了)
(7)当容器关闭,调用bean的销毁的方法。
后置处理器实现:
实现
创建方法
配置bean
结果:
四、IOC操作Bean管理(xml自动装配)
Alt+insert快捷插入get、set方法
1.什么是自动装配
根据指定装配规则(属性名或属性类型),Spring自动将匹配的属性值注入。
2.配置过程
(1)根据属性名称byName
(2)根据属性类型byType(相同类型的只能用一个,否则用属性名称)
五、IOC操作Bean管理(外部属性文件)
1.直接读取数据库信息
(1)配置德鲁伊连接池
(2)引入德鲁伊连接池依赖jar.包,网址
Central Repository: com/alibaba/druid
2.引入外部属性文件配制数据库连接池
(1)创建外部属性文件,properties格式文件,写入数据库信息。
(2)把外部properties属性文件引入到spring配置文件
在spring配置文件中用标签引入
六、IOC操作Bean管理(基于注解方式)
1.什么是注解
(1)注解是代码特殊标记,格式:@注解名(属性名称=属性值,属性名称=属性值)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解的目的:简化xml配置
2.Spring针对Bean管理创建对象提供注解
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
上面四个注解功能一样,都可以用来创建Bean实例。
3.基于注解方式实现对象的创建。
(1)引入依赖
(2)开启组件扫描
配置context
(3)创建类,加上注解
结果
七、AOP(概念)
1.什么是AOP
(1)面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2) 通俗描述,不通过修改源代码方式,在主干功能里面添加新功能。
(3)使用登录的例子来说明AOP
2.AOP底层原理
(1)AOP底层使用动态代理
第一种:有接口情况,使用JDK动态代理。
创建接口实现类的代理对象,增强类的方法
第二种:没有接口情况,使用CGLIB动态代理。
创建当前类的子类代理对象
(2)AOP(JDK动态代理)
1、使用JDK动态代理,使用Proxy类里面的方法创建代理
(1)调用newProxyInstance方法
方法有三个参数
第一个参数:类加载器
第二个参数:增强方法所在的类,这个类实现的接口,支持多个接口
第三个参数:实现这个接口的InvocationHandler,创建代理对象,写增强的方法
2、JDK动态代理代码
(1)创建接口,定义方法
(2)创建接口实现类,实现方法
(3)使用Proxy类创建接口代理对象
package test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; public class JDKprocxy { //创建接口实现类代理对象 public static void main(String[] args) { Class[] interfaces = {UserDao.class}; /* Proxy.newProxyInstance(JDKprocxy.class.getClassLoader(), interfaces, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } }); }*/ UserDaoimtl userDao = new UserDaoimtl(); UserDao dao=(UserDao)Proxy.newProxyInstance(JDKprocxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int result = dao.add(1, 2); System.out.println("result:" + result); } } class UserDaoProxy implements InvocationHandler { //吧创建的是谁的代理对象,传递过来 //把参数构造传递 private Object obj; public UserDaoProxy(Object obj) { this.obj = obj; } //增强逻辑 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //方法之前处理 System.out.println("在方法之前执行......" + method.getName() + ":传递的参数...." + Arrays.toString(args)); //方法执行 Object res = method.invoke(obj, args); //方法之后处理 System.out.println("在方法之后执行......" + obj); return res; } }
八、AOP(术语)
1.连接点
类里面哪些方法可以被增强,这些方法称为连接点。
2.切入点
实际被真正增强的方法,称为切入点。
3.通知(增强)
(1)实际增强的逻辑部分称为通知(增强)。
(2)通知有多种类型
前置通知:后置通知:环绕通知:异常通知:最终通知:finally 最终都会执行
4.切面
是动作
(1)把通知应用到切入点的过程。
AOP操作(准备)
1.Spring框架一般基于AspectJ实现AOP操作
(1)什么是AspectJ
AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作。
2.基于AspectJ实现AOP操作
(1)基于xml配置文件实现
(2)基于注解方式实现(使用)
3.在项目工程里面引入AOP相关依赖
4.切入点表达式
(1)切入点表达式作用:知道对那个类里面的那个方法进行增强
execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
举例1:对test.dao.BookDao类里面的add进行增强
execution(* test.dao.BookDao.add(..))
举例2::对test.dao.BookDao类里面的所有进行方法增强
execution(* test.dao.BookDao.*(..))
举例3::对test.dao包里面的所有类中的所有方法进行增强
execution(* test.dao.*.*(..))
AOP操作(AspectJ注解)
1.创建类,在类里面定义方法
package Aop;
public class User {
public void add(){
System.out.println("add......" );
}
}
2.创建增强类(编写增强逻辑)
(1)在增强类里面,创建方法,让不同方法代表不同的通知类型
package Aop;
public class UserProxy { //前置通知
public void before(){
System .out .println("before..."); }
}
3.进行通知的配置
(1)在Speing配制文件中,开启注解扫描。
<?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-context.xsd">
<context:component-scan base-package="Aop"></context:component-scan>
</beans>
(2)使用注解创建User和UserProxy对象。
(3)在增强类上面添加注解@Aspect。
(4)在Spring配制文件中开启生成代理对象。
<!--开启Aspect生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
4.配制不同类型的通知
(1)在增强类中,在作为通知的方法上面添加通知类型注解,使用切入点表达式进行配置
@Component
@Aspect
public class UserProxy {
//前置通知
//@before注解表示作为前置通知
@Before(value="execution(* Aop.User.add(..)) ")
public void before(){
System .out .println("before...");
}
}
@Component
@Aspect
public class UserProxy {
//前置通知
//@before注解表示作为前置通知
@Before(value="execution(* Aop.User.add(..)) ")
public void before(){
System .out .println("before...");
}
@After(value="execution(* Aop.User.add(..)) ")
public void after(){
System .out .println("after...");
}
@AfterReturning(value="execution(* Aop.User.add(..)) ")
public void AfterReturning(){
System .out .println("AfterReturning...");
}
//异常通知
@AfterThrowing(value="execution(* Aop.User.add(..)) ")
public void AfterThrowing(){
System .out .println("AfterThrowing...");
}
@Around(value="execution(* Aop.User.add(..)) ")
public void around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
System.out .println("环绕之前");
proceedingJoinPoint.proceed();
System.out .println("环绕之后");
}
Afterreturning(后置通知)返回通知
After不论如何都在方法后执行(最终通知)
Afterthrowing异常通知,出错才执行
aroud(出错,环绕之前执行,环绕之后不执行)
5.相同切入点抽取
@Pointcut(value="execution(* Aop.User.add(..)) ")
public void point(){
}
6.有多个增强类对用一个方法进行增强,设置增强类优先级
在增强类上面添加注解@Order(数字类型值),值越小,优先级越高
7.完全使用注解开发
(1)创建配制类,不需要创建xml配制文件
@Configuration
@ComponentScan(basePackages = {"AopXml"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigureAop {
}
九、JdbcTemplate(概念和准备)
1.什么是jdbcTemplate
(1)Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库的操作。
2、准备工作
(1)引入相关jar包
(2)在spring配置文件数据库连接池
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="jdbc:mysql:///user_db" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
(3)配置JdbcTemplate对象,注入DataSource
<!--JdbcTemplate对象-->
<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入datasource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
(4)创建service类,创建dao类,在dao注入jdbcTemplate
配制文件中,开启组件扫描
<!-- 组件扫描 -->
<context:component-scan base-package="dao"></context:component-scan>
<context:component-scan base-package="service"></context:component-scan>
Service
package service;
import dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BookService {
//注入dao
@Autowired
private BookDao bookDao ;
}
Dao
package dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class BookDaoImpl implements BookDao {
@Autowired
private JdbcTemplate jdbcTemplate ;
}
jdbcTemplate操作数据库(添加)
1.对应数据库
2.编写service和dao
(1)在dao进行数据库添加操作
(2)调用jdbctemplate对象里面updata方法实现添加操作
有两个参数
第一个参数,sql语句
第二个参数,可变参数,设置sql 语句值
@Repository
public class BookDaoImpl implements BookDao {
@Autowired
private JdbcTemplate jdbcTemplate ;
@Override
public void add(Book book) {
String sql="insert into t_book values(?,?,?)";
Object [] args ={book.getUserId(), book.getUsername(), book.getUstatus()};
int update = jdbcTemplate.update(sql,args);
System .out .println(update) ;
}
}