总结
虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。
上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料
有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
(2)创建接口的实现类
package com.itzheng.spring.demo1;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println(“保存用户。。。。”);
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println(“修改用户。。。。”);
}
@Override
public void find() {
// TODO Auto-generated method stub
System.out.println(“查询用户。。。。”);
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println(“删除用户。。。”);
}
}
(3)创建动态代理
- 编写一个类实现InvocationHandler接口
通过Proxy.newProxyInstance获取到UserDao的代理对象,通过invoke方法实现对UserDao 类方法的增加
如果执行的save方法就执行代理对象,如果是是别的方法就执行原本的类当中的方法
package com.itzheng.spring.demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
- 使用JDK的动态代理对UserDao产生代理
*/
public class JDKProxy implements InvocationHandler{
// 将被增强的对象传递到代理当中
private UserDao userDao;
public JDKProxy(UserDao userDao) {
this.userDao = userDao;
}
/*
- 产生UserDao代理的
*/
public UserDao createProxy() {
//获取到UserDao的代理
UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance( userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(),this );
//将userDao代理返回
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断方法名是不是save:
if(“save”.equals(method.getName())) {
//增强:在原有的方法上,进行权限校验
System.out.println(“权限校验=====================”);
return method.invoke(userDao, args);
}
return method.invoke(userDao, args);//执行该方法
}
}
(4)创建测试类进行测试
package com.itzheng.spring.demo1;
import org.junit.Test;
public class SpringDemo1 {
@Test
//JDK 动态代理
public void demo1() {
UserDao userDao = new UserDaoImpl();
//创建代理
UserDao proxy = new JDKProxy(userDao).createProxy();
proxy.save();
proxy.update();
proxy.find();
proxy.delete();
}
}
2、Cglib动态代理
(1)简述:第三方的开源的代码生成类库,动态的去添加类的属性和方法。
- 引入Spring符基本jar
- 在Spring的jar当中就有cglib,所以引入Spring的jar就直接可以使用cglib
(2)创建CustomerDao类
package com.itzheng.spring.demo2;
public class CustomerDao {
public void save() {
System.out.println(“保存客户”);
}
public void find() {
System.out.println(“查询客户”);
}
public void update() {
System.out.println(“修改客户”);
}
public void delete() {
System.out.println(“删除客户”);
}
}
(3)创建CglibProxy 类实现MethodInterceptor 接口
-
CustomerDao 原本没有父类通过setSuperclass的方式为其设置父类,
-
设置父类以后CustomerDao
就相当于是子类,可以拓展方法,如果如果是save方法就执行增强类(子类)因为方法相同所以增强后,直接执行invokeSuper方法以及增强的方法,如果不是save方法就执行执行父类
package com.itzheng.spring.demo2;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
//Cglib动态代理
public class CglibProxy implements MethodInterceptor {
private CustomerDao customerDao;
public CglibProxy(CustomerDao customerDao) {
this.customerDao = customerDao;
}
/*
- 提供cglib产生代理的方法
*/
public CustomerDao createProxy() {
// 1、创建cglib的核心类对象
Enhancer enhancer = new Enhancer();
// 2、设置父类
enhancer.setSuperclass(customerDao.getClass());
// 3、设置回调(类似于InvacationHandler对象)
enhancer.setCallback(this);// 执行实现接口当中的方法,也就是下面的intercept方法
//4、创建代理对象
CustomerDao proxy = (CustomerDao) enhancer.create();
return proxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// TODO Auto-generated method stub
// 判断方法是否为save1
if (“save”.equals(method.getName())) {
// 增强
System.out.println(“权限校验”);
// 增强后执行customerDao
return methodProxy.invokeSuper(proxy, args);
}
// 如果不是save执行父类的方法(父类就没有增强)
return methodProxy.invokeSuper(proxy, args);
}
}
(4)创建测试类
package com.itzheng.spring.demo2;
import org.junit.Test;
public class SpringDemo2 {
@Test
public void demo1() {
CustomerDao customerDao = new CustomerDao();
CustomerDao proxy = new CglibProxy(customerDao).createProxy();
proxy.save();
proxy.update();
proxy.find();
proxy.delete();
}
}
- 结果
二、Spring的AOP的开发(AspectJ的XML的方式)
1、Spring的AOP的简介
(1)AOP思想最早是由AOP联盟组织提出的。Spring使用这种思想的最好的框架。
- Spring的AOP有自己的实现方式(非常繁琐)---->
AspectJ是一个AOP框架,Spring在后期的版本当中引入AspectJ作为自身AOP的开发。
-
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
-
Spring两套AOP的开发方式
a、Spring传统方式(弃用)
b、Spring基于AspectJ的AOP的开发(使用)
2、AOP开发中相关的术语
-
Joinpoint:连接点
-
Pointcut:切入点
-
Advice:通知/增强
-
Introduction:引介
-
Target:被增强对象
-
Weaving:织入
-
Proxy:代理对象
-
Aspect:切面
2、Spring的AOP入门(AspectJ的XML的方式)
(1)创建web项目,引入jar
- a、引入Spring的基本开发包
- b、引入aop开发的相关的4个jar
依赖包下载:spring3.0.2.dependencies.jar
下载链接:https://download.csdn.net/download/qq_44757034/12585722
- AOP联盟的依赖包
- 引入Spring的AOP开发包
引入以上两个包就可以进行Spring传统的开发
如果要进行AspectJ的开发还需要引入两个jar包
- 引入在aspectj当中的aspectj依赖包当中aspectj.weaver的依赖包
- 引入Spring和aspectj整合的jar
- c、一共引入了10个jar
(2)引入Spring的配置文件
- a、引入aop约束
在这个路径下的HTML文件: spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\ xsd-configuration.html
- b、设置XML提示
- c、在src下创建创建applicationContext.xml并引入aop约束
<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” 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">
(3)编写目标类并完成配置
- a、创建CustomerDao
package com.itzheng.spring.demo2;
public class CustomerDao {
public void save() {
System.out.println(“保存客户”);
}
public void find() {
System.out.println(“查询客户”);
}
public void update() {
System.out.println(“修改客户”);
}
public void delete() {
System.out.println(“删除客户”);
}
}
- b、创建ProductDao 的实现类ProductDaoImpl
package com.itzheng.spring.demo3;
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println(“保存商品。。。”);
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println(“修改商品”);
}
@Override
public void find() {
// TODO Auto-generated method stub
System.out.println(“查询商品”);
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println(“删除商品”);
}
}
- c、在applicationContext.xml文件当中配置目标对象
(4)编写目测试类:
- a、引入Spring整合单元测试的jar
- b、测试
@RunWith(SpringJUnit4ClassRunner.class) // 引入Spring整合单元测试
@ContextConfiguration(“classpath:applicationContext.xml”) // 加载配置文件
@Resource(name = “productDao”) // 注入对象productDao在配置文件当中指的是ProductDaoImpl
package com.itzheng.spring.demo3;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/*
- AOP入门
*/
@RunWith(SpringJUnit4ClassRunner.class) // 引入Spring整合单元测试
@ContextConfiguration(“classpath:applicationContext.xml”) // 加载配置文件
public class SpringDemo3 {
@Resource(name = “productDao”) // 注入对象productDao在配置文件当中指的是ProductDaoImpl
private ProductDao productDao;
@Test
public void demo1() {
productDao.save();
productDao.update();
productDao.find();
productDao.delete();
}
}
最后
笔者已经把面试题和答案整理成了面试专题文档
emo3 {
@Resource(name = “productDao”) // 注入对象productDao在配置文件当中指的是ProductDaoImpl
private ProductDao productDao;
@Test
public void demo1() {
productDao.save();
productDao.update();
productDao.find();
productDao.delete();
}
}
最后
笔者已经把面试题和答案整理成了面试专题文档
[外链图片转存中…(img-RD4p71hj-1715471201351)]
[外链图片转存中…(img-YT0yUMNE-1715471201351)]
[外链图片转存中…(img-IPmzqft8-1715471201352)]
[外链图片转存中…(img-puFN8QgL-1715471201352)]
[外链图片转存中…(img-wb4Qltl7-1715471201352)]
[外链图片转存中…(img-gA12mvZm-1715471201353)]