本文是在看了b站的
尚硅谷Spring5框架教程(idea版)
总结出来的笔记以及见解
尚硅谷Spring框架学习笔记(上):
AOP(概念)
1.什么是AOP
(1)面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2)通俗描述就是:不通过修改源代码的方式添加新功能
(3)使用登录的例子来说明AOP
AOP(底层原理)
1.AOP底层使用动态代理
(1)有两种情况的动态代理
第一种情况:有接口,使用JDK动态代理(动态代理spring5已经进行了封装)
*创建借口实现类代理对象,增强类的方法
第二种情况:没有接口,使用CGLIB动态代理
*创建子类的代理对象,增强类的方法
AOP(JDK动态代理)
1.使用JDK动态代理,使用Proxy类里面的方法创建代理对象 (1)调用newProxyInstance方法
方法有三个参数:
第一个参数:是类加载器
第二个参数:增强方法所在的类,这个类实现的接口,支持多个接口
第三个参数,实现里面的接口InvocationHandler,创建代理对象,写增强的方法
2.JDK动态代理代码编写
(1)创建接口,定义方法
public interface UserDao {
public int add(int a,int b) ;
public void update(String id);
}
(2)创建接口的实现类,实现方法
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
System.out.println("add方法被执行了....");
return a+b;
}
@Override
public String update(String id) {
System.out.println("update被执行了.....");
return id;
}
}
(3)使用Proxy类创建接口代理对象
public class JDKProxy {
public static void main(String[] args) {
Class[] interfaces = { UserDao.class };
UserDaoImpl userDao = new UserDaoImpl();
UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces,
new UserDaoProxy(userDao));
System.out.println("--------------------------");
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.通知(增强)
4.切面
AOP操作(准备)
1.spring框架一般都是基于AspectJ实现AOP操作
(1)什么是AspectJ
*AspectJ不是Spring组成的部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作
2.基于AspectJ实现AOP操作
(1)基于xml配置文件实现
(2)基于注解方式实现(使用)
3.在项目工程里面引入AOP相关依赖
4.切入点表达式
(1)切入表达式作用:知道哪个类里面的那个方法进行增强
(2)语法结构
execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))
举例1:对com.atguigu.dao.BookDao;类里面的add进行增强
execution(*com.atguigu.dao.BookDao.add(…))
举例2:对com.atguigu.dao.BookDao类里面所有方法进行增强
execution(*com.atguigu.dao.BookDao. *(…))
举例3::对com.atguigu.dao包里面所有方法进行增强
execution(*com.atguigu.dao. *. *(…))
AOP操作(AspectJ注解)
1.创建类,在类里面定义方法
public class User {
public void add() {
System.out.println("add........");
}
}
2.创建增强类(编写增强逻辑)
(1)在增强类里面,创建方法,让不同方法代表不同通知类型
public class UserProxy {
public void before() {
System.out.println("before.......");
}
}
3.进行通知配置
(1)在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"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启组件扫描 -->
<context:component-scan
base-package="pdsu.edu.aopanno"></context:component-scan>
</beans>
(2)使用注解创建User和UserProxy对象
@Component
public class User {
public void add() {
System.out.println("add........");
}
}
@Component
public class UserProxy {
public void before() {
System.out.println("before.......");
}
}
(3)在增强类上面添加注解@Aspect
@Component
@Aspect
public class UserProxy {
public void before() {
System.out.println("before.......");
}
}
(4)在spring配置文件中开启生成代理对象
<!-- 开启Aspect生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
4.配置不同类型的通知
(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
@Component
@Aspect
public class UserProxy {
@Before(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void before() {
System.out.println("before.......");
}
@After(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void after() {
System.out.println("After........");
}
@AfterReturning(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void afterReturning() {
System.out.println("afterReturning........");
}
@AfterThrowing(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void afterThrowing() {
System.out.println("afterThrowing........");
}
@Around(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前........");
proceedingJoinPoint.proceed();
System.out.println("环绕之后........");
}
}
测试
public class test1 {
public static void main(String[] args) {
ApplicationContext con =new ClassPathXmlApplicationContext("bean1.xml");
User user = con.getBean("user",User.class);
user.add();
}
}
运行结果:
环绕之前… before… add… afterReturning… After… 环绕之后…
*@After,@AfterReturning都是程序执行后执行
区别:@After方法之后执行,一定执行
? @AfterReturning返回值(后置通知)之后执行,有异常不通知
@AfterThrowing//异常通知(没有异常不通知)
5.相同切入点抽取,修改方便
@Pointcut(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void pointdemo() {
}
@Before(value="pointdemo()")
public void before() {
System.out.println("before.......");
}
6.有多个增强类执行同一个方法,设置增强类优先级
(1)在增强类的上面添加注释@Order(数字类型),数字值越小优先级越高,最小为0(控制台最后打印结果)
@Component
@Aspect
@Order(0)
public class PersonProxy {
@AfterReturning(value="execution(* pdsu.edu.aopanno.User.add(..))")
public void afterReturning() {
System.out.println("PersonProxy afterReturning........");
}
}
7.完全使用注解开发
(1)创建配置类,不需要xml文件
@CacheConfig
@ComponentScan(basePackages = "pdsu.edu.aopxml")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}
AOP操作(ASpectJ配置文件,了解)
1.创建两个类,增强类和被增强类,创建方法
2.在spring配置文件中创建两个类对象
3.在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"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 创建对象 -->
<bean id="book" class="pdsu.edu.aopxml.Book"></bean>
<bean id="bookProxy" class="pdsu.edu.aopxml.BookProxy"></bean>
<!-- 配置aop增强 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut
expression="execution(* pdsu.edu.aopxml.Book.buy(..))" id="p" />
<!-- 配置切面 -->
<aop:aspect ref="bookProxy">
<!-- 增强作用具体到方法上 -->
<aop:before method="before" pointcut-ref="p" />
</aop:aspect>
</aop:config>
</beans>
JdbcTemplate(概念和准备)
1.什么是JdbcTemplate
(1)Spring框架对JDBC进行封装,使用JdbcTemplate方便实现
2.准备工作
(1)引入相应的jar包
(2)在spring配置文件配置数据库连接池
<!-- 先引入外部属性文件 -->
<context:property-placeholder location="classpath :jdbc.properties"/>
<!-- 数据库连接池 -->
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName"
value="${prop.driverClassName}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.username}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
jdbc.properties文件
prop.driverClassName=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/text
prop.username=root
prop.password=123456
(3)配置JdbcTemplate对象,注入DataSource
<!-- JdbcRemplate对象 -->
<bean id="jdbcTemplate" class="org.spring framework.jdbc.core.JdbcTemplate">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
(4)创建service 类,创建dao类,在dao注入JdbcTemplate对象
*配置文件
<!-- 开启注解扫描 -->
<context:component-scan base-package="pdsu.edu"></context:component-scan>
<!-- JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
Service类
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void addBook(Book book) {
bookDao.add(book);
}
}
Dao类
@Repository
public class BookDaoImpl implements BookDao{
@Autowired
private JdbcTemplate jdbcJdbcTemplate;
}
JdbcTemplate操作数据(添加)
1.对应数据库创建实体类
public class User {
private String userId;
private String username;
private String ustatus;
public void setUserId(String userId) {
this.userId = userId;
}
public void setUsername(String username) {
this.username = username;
}
public void setUstatus(String ustatus) {
this.ustatus = ustatus;
}
public String getUserId() {
return userId;
}
public String getUsername() {
return username;
}
public String getUstatus() {
return ustatus;
}
}
2.编写service和dao
(1)在dao进行进行数据库添加操作
(2)调用JdbcTemplate对象里面update方法实现添加操作
update(String sql,Object…args)
*有两个参数
第一个参数:是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 data =jdbcTemplate.update(sql,args);
System.out.println(data);
}
}
3.测试类
public class test {
public static void main(String[] args) {
ApplicationContext con =
new ClassPathXmlApplicationContext("bean1.xml");
BookService bookService = con.getBean("bookService",BookService.class);
Book book1 = new Book("1","java","a");
Book book2 = new Book("2","ph","b");
bookService.addBook(book1);
bookService.addBook(book2);
}
}
jdbcTemplate操作数据库(修改和删除)
修改操作:
@Override
public void updateBook(Book book) {
Object[] args= {book.getUsername(),book.getUstatus(),book.getUserId()};
String sql="update t_book set username=?,ustatus=? where user_id=?";
int update = jdbcTemplate.update(sql, args);
System.out.println(update);
}
删除操作:
@Override
public void deleteBook(String id) {
String sql = "delete from t_book where user_id=?";
int update = jdbcTemplate.update(sql, id);
System.out.println(update);
}
测试:
bookService.deleteBook("2");
jdbcTemplate操作数据库(查询返回某个值)
1.查询表里面有多少记录,返回某个值
2.使用JdbcTemplate
有两个参数
*第一个参数:sql语句
*第二个参数:返回类型的class
@Override
public int selectCount() {
String sql = "select count(*) from t_book";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
return count;
}
jdbcTemplate操作数据库(查询返回对象)
1.场景:查询图书详情
2.JdbcTemplate实现查询返回对象
有三个参数
*第一个参数:sql语句
*第二个参数:RowMapper,是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
*第三个参数:sql语句值
@Override
public Book findBookInfo(String id) {
String sql ="select * from t_book where user_id=?";
Book book= (Book) jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class),id);
return book;
}
jdbcTemplate操作数据库(查询返回集合)
1.场景:查询图书列表分页…
2.调用JdbcTemplate方法实现返回集合
有三个参数
*第一个参数:sql语句
*第二个参数:RowMapper,是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
*第三个参数:sql语句值(可以没有)
@Override
public List<Book> findAllBook() {
String sql = "select * from t_book";
List<Book> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
return list;
}
JdbcTemplate操作数据库(批量添加操作)
1.批量操作:操作表里面多条记录
2.JdbcTemplate实现批量添加操作
有两个参数
*第一个参数:sql语句
*第二个参数:List集合,添加多条记录数据
@Override
public void batchAddBook(List<Object[]> batchArgs) {
String sql="insert into t_book values(?,?,?)";
int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
System.out.println(Arrays.toString(ints));
}
测试:
List<Object[]> batchArgs =new ArrayList<>();
Object[] o1 = {"3","javac","a"};
Object[] o2 = {"4","c++","b"};
Object[] o3 = {"5","MySQL","c"};
batchArgs.add(o1);
batchArgs.add(o2);
batchArgs.add(o3);
bookService.batchAdd(batchArgs);
JdbcTemplate操作数据库(批量修改操作)
@Override
public void batchUpdateBook(List<Object[]> batchArgs) {
String sql="update t_book set username=?,ustatus=? where user_id=?";
int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
System.out.println(Arrays.toString(ints));
}
@Override
public void batchDeleteBook(List<Object[]> batchArgs) {
String sql = "delete from t_book where user_id=?";
int[] ints = jdbcTemplate.batchUpdate(sql,batchArgs);
System.out.println(Arrays.toString(ints));
}
测试:
后续笔记会持续更新,希望大家给个一键三连!!!!!
|