关于Spring中IOC的使用链接
(14条消息) spring boot整合shiro实现登录认证授权你_qq_59776041的博客-CSDN博客_shiro
AOP
AOP概念
-
什么是AOP
-
面向切面编程
-
利用AOP可以对业务逻辑的各个方面进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
-
通俗描述:不通过改源代码的方式,在主干功能里面添加新的功能
-
AOP的底层原理
-
AOP的底层使用动态代理
两种动态代理
-
有接口,使用JDK动态代理
-
创建接口实现类代理对象,增强类的方法
-
-
没有接口,使用CGLIB动态代理
-
创建当前子类的代理对象,增强类的方法
-
-
AOP(JDK动态代理)
-
使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
-
调用newProxyInstance
-
loader:类加载器
-
interfaces:增强方法所在的类,这个类实现的接口,支持多个接口
-
h:实现接口InvocationHandler,创建代理对象,写增强的方法
-
-
-
JDK动态代理代码
-
创建接口,定义方法
public interface UserDao { public int add(int a,int b); public String update(String id); }
-
创建接口实现类,实现方法
public class UserDaoImpl implements UserDao{ @Override public int add(int a, int b) { return a+b; } @Override public String update(String id) { return id; } }
-
-
使用Proxy类创建接口代理对象
public class JDKProxy { public static void main(String[] args) { //创建接口实现类代理对象 Class[] interfaces = {UserDao.class}; // Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() { // @Override // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // return null; // } // }); UserDaoImpl userDao = new UserDaoImpl(); UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int add = dao.add(1, 4); System.out.println(add); } } //创建代理对象代码 class UserDaoProxy implements InvocationHandler{ // 1.把创建增强类传入 有参数构造传递 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 invoke = method.invoke(obj, args); //方法之后 System.out.println("方法之后执行..."+obj); return invoke; } }
AOP(术语)
-
连接点:
类里面哪些方法可以被增强,这些方法称为连接点
-
切入点:
实际被增强的方法,称为切入点
-
通知(增强):
-
实际增强的逻辑部分被称为通知
-
通知有很多种类型
-
前置通知
-
后置通知
-
环绕通知
-
异常通知
-
最终通知
-
-
-
切面:
把通知应用到切入点的过程(是个动作)
AOP(准备)
-
Spring基于 AspectJ 实现 AOP 操作
-
什么是AspectJ
AspectJ不是 Spring 组成部分,对立 AOP 框架,一般把 Spring 和 AspectJ 一起使用,进行AOP操作
-
-
基于AspectJ实现AOP操作
-
xml配置文件
-
注解方式
-
-
在项目工程里引入AOP相关依赖
-
切入点表达式
-
切入点表达式作用:知道对哪个类哪个方法进行增强
-
语法结构:
execution([权限修饰符] [返回类型] [类群路径] [方法名称] ([参数列表]) )
举例一:对com.company.UserDao类里面的add方法进行增强 execution(* com.company.UserDao.add(..))
举例二:对com.company.BookDao类里面所有方法进行增强 execution(* com.company.BookDao.*(..))
举例二:对com.company包里面所有类的所有方法进行增强 execution(* com.company.* . *(..))
-
AOP操作(注解)
-
创建类,定义要被增强的方法
-
创建增强类(编写增强逻辑)
-
在增强类里面,创建方法,让不同方法代表不同通知类型
-
-
进行通知的配置
-
在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: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-aop.xsd"> <!-- 开启注解扫描--> <context:component-scan base-package="com.company.aopanno"></context:component-scan> </beans>
-
使用注解创建 User 和 UserProxy 对象
-
在增强类上面添加@Aspect
-
在 spring 配置文件中开启生成代理对象
<!-- 开启注解扫描--> <context:component-scan base-package="com.company.aopanno"></context:component-scan> <!-- 开启aspectJ生成代理的对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
-
配置不同类型的通知
@Aspect //生成代理对象 @Component public class UserProxy { @Before(value = "execution(* com.company.aopanno.User.add(..))") public void before(){ System.out.println("before、、、、、"); } //最终通知 @After(value = "execution(* com.company.aopanno.User.add(..))") public void after(){ System.out.println("after、、、、、"); } //后置通知(返回通知) @AfterReturning(value = "execution(* com.company.aopanno.User.add(..))") public void afterReturning(){ System.out.println("AfterReturning、、、、、"); } //异常通知 @AfterThrowing(value = "execution(* com.company.aopanno.User.add(..))") public void afterThrowing(){ System.out.println("AfterThrowing、、、、、"); } @Around(value = "execution(* com.company.aopanno.User.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("around1、、、、、"); //被增强的方法执行 proceedingJoinPoint.proceed(); System.out.println("around2、、、、、"); } }
-
相同的切入点抽取
//相同的切入点抽取 @Pointcut(value = "execution(* com.company.aopanno.User.add(..))") public void pointDemo(){ } @Before(value = "pointDemo()") public void before(){ System.out.println("before、、、、、"); }
-
-
有多个增强类对同一个方法增强,设置增强优先级
-
在增强类上添加@Order(数字类型值),值越小优先级越高
-
AOP操作(AspectJ配置文件)
-
创建两个类增强类和被增强类,创建方法
-
在spring配置文件中创建两个类对象
-
在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: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-aop.xsd"> <!-- 创建对象--> <bean id="book" class="com.company.aopxml.Book"></bean> <bean id="bookProxy" class="com.company.aopxml.BookProxy"></bean> <!-- 配置aop增强--> <aop:config> <!-- 切入点--> <aop:pointcut id="p" expression="execution(* com.company.aopxml.Book.buy(..))"/> <!-- 配置切面--> <aop:aspect ref="bookProxy"> <!-- 增强的具体方法--> <aop:before method="before" pointcut-ref="p"/> </aop:aspect> </aop:config> </beans>
AOP(全注解)
-
创建配置类
@Configuration @ComponentScan(basePackages = {"com.company"}) @EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAop { }
JdbcTemplate
JdbcTemplate概念及使用
-
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
-
引入相关 jar 包
-
组件扫描
<!-- 组件扫描 --> <context:component-scan base-package="com.aijj"></context:component-scan>
-
在 spring 配置文件配置
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="jdbc:mysql:///test" /> <property name="username" value="root" /> <property name="password" value="root" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> </bean>
-
配置 JdbcTemplate 对象,注入 DataSource
<!-- JdbcTemplate 对象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!--注入 dataSource--> <property name="dataSource" ref="dataSource"></property><!--set方式注入--> </bean>
-
创建 service 类,创建 dao 类,在 dao 注入 jdbcTemplate 对象
@Service public class BookService { //注入 dao @Autowired private BookDao bookDao; } @Repository public class BookDaoImpl implements BookDao { //注入 JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; }
JdbcTemplate 操作数据库
-
对应实体类、dao层和service层
-
在dao层进行数据库的操作
-
调用 JdbcTemplate 对象里面 update 方法实现添加操作
@Repository public class BookDaoImpl implements BookDao { //注入 JdbcTemplate @Autowired private JdbcTemplate jdbcTemplate; //添加的方法 @Override public void add(Book book) { //1 创建 sql 语句 String sql = "insert into t_book values(?,?,?)"; //2 调用方法实现 Object[] args = {book.getUserId(), book.getUsername(),book.getUstatus()}; int update = jdbcTemplate.update(sql,args); System.out.println(update); } }
-
修改和删除也是调用update方法
//1、修改 @Override public void updateBook(Book book) { String sql = "update t_book set username=?,ustatus=? where user_id=?"; Object[] args = {book.getUsername(), book.getUstatus(),book.getUserId()}; int update = jdbcTemplate.update(sql, args); System.out.println(update); } //2、删除 @Override public void delete(String id) { String sql = "delete from t_book where user_id=?"; int update = jdbcTemplate.update(sql, id); System.out.println(update); } //使用JdbcTemplate 模板所实现的 “增删改” 都是调用了同一个 “update” 方法
-
查询操作
-
返回某些值~~~调用queryForObject方法
//查询表记录数 @Override public int selectCount() { String sql = "select count(*) from t_book"; //queryForObject方法中:第一个参数代表--sql语句;第二个参数代表--返回类型class Integer count = jdbcTemplate.queryForObject(sql, Integer.class); return count; }
-
返回对象值~~~调用queryForObject方法
//查询返回对象 @Override public Book findBookInfo(String id) { String sql = "select * from t_book where user_id=?"; //调用方法 /* queryForObject方法中: 第一个参数:sql语句 第二个参数:RowMapper 是接口,针对返回不同类型数据,使用这个接口里面 实现类 完成数据封装 第三个参数:sql 语句值 */ Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id); return book; }
-
查询返回集合~~~调用query函数
//所用场景:查询图书列表分页、、 //查询返回集合 @Override public List<Book> findAllBook() { String sql = "select * from t_book"; //调用方法 List<Book> bookList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class)); return bookList; }
-
批量操作数据库~~~调用batchupdate函数
//批量添加 @Override public void batchAddBook(List<Object[]> batchArgs) { String sql = "insert into t_book values(?,?,?)"; //batchUpdate方法 第一个参数:sql语句 第二个参数:List集合,添加多条记录数据 int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs); System.out.println(Arrays.toString(ints)); } //批量添加测试 List<Object[]> batchArgs = new ArrayList<>(); Object[] o1 = {"3","java","a"}; Object[] o2 = {"4","c++","b"}; Object[] o3 = {"5","MySQL","c"}; batchArgs.add(o1); batchArgs.add(o2); batchArgs.add(o3); //调用批量添加 bookService.batchAdd(batchArgs);
-
批量修改数据库~~~调用batchupdate函数
//批量修改(同批量添加一样,调用同一个方法) @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)); }
-
-