《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
proxy类对应的4个静态方法:
========================================================================
Rent接口:
package com.itholmes.demo3;
public interface Rent {
void rent();
}
Host类(房东):
package com.itholmes.demo3;
public class Host implements Rent{
@Override
public void rent() {
System.out.println(“房东要出租房子!”);
}
}
ProxyInvocationHandler.java实现InvocationHandler接口的类,这个类可以自动生成代理类。
package com.itholmes.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//我们会用这个类自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成得到代理类
//第一个参数,类构造器:this.getClass().getClassLoader()加载到代理类在那个位置。
//第二个参数,得到实现rent的接口:rent.getClass().getInterfaces()表示它要代理的接口是哪一个接口。
//第三个参数,实现InvocationHandler的类,这里我们本身就实现了InvocationHandler了,所以用this就可,。
public Object getProxy(){
Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
//System.out.println(“判断o:”+o);
return o;
}
//上面的Proxy.newProxyInstance()方法执行后,会执行当前的invoke方法来处理代理实例,并返回结果。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
//动态代理的本质,就是使用反射机制实现的!
Object invoke = method.invoke(rent, args);
//System.out.println(“判断invoke:”+invoke);
fare();
return invoke;
}
//我们可以通过打印来判断这里的invoke对象和上面的o对象是一个对象么?
//invoke:com.itholmes.demo3.Host@2b193f2d
//getProxy:com.itholmes.demo3.Host@2b193f2d
//返回结果不难看出就是一个对象。
public void seeHouse(){
System.out.println(“中介带看房子”);
}
public void fare(){
System.out.println(“中介收费”);
}
}
Client用户测试类:
package com.itholmes.demo3;
public class Client {
public static void main(String[] args) {
//真实角色(房主)
Host host = new Host();
//代理角色(中介):现在没有
ProxyInvocationHandler handler = new ProxyInvocationHandler();
//通过调用程序处理角色(当前我们定义的ProxyInvocationHandler类)来处理我们要调用的接口对象。
handler.setRent(host);
Rent proxy = (Rent)handler.getProxy();//这里的proxy就是动态生成的!
proxy.rent();
}
}
**此外,invoke中的method方法可以调用很多方法,例如:
method.getName()获取名字等等。**
===========================================================================
面向对象程序设计(Object Oriented Programming , OOP)
面向切面编程:(Aspect Oriented Programming , AOP)
AOP是OOP的延续。
AOP的一个效果图如下:
SpringAOP中,通过Advice定义横切逻辑。
在Spring中支持5种类型的Advice:
6. 实现aop(一) 通过SpringAPI接口实现(围绕接口来实现)
==================================================================================================
实现AOP前,需要一个织入依赖包aspectjweaver!
导入完包后,要导入响应的约束和支持约束条件:
其实不管什么约束条件都是差不多的格式,稍微改改字母就能修改。
xmlns:aop=“http://www.springframework.org/schema/aop”
xsi:schemaLocation="
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd"
上面准备工作完成后,我们创建两个类分别实现了AfterReturningAdvice 和 MethodBeforeAdvice接口:
log类实现MethodBeforeAdvice方法执行前调用它:
package com.itholmes.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice{
//before方法的参数:
//method:要执行的目标对象的方法
//objects:参数
//o:目标对象
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName()+“的”+method.getName()+“被执行了”);
}
}
AfterLog类,调用AfterReturningAdvice接口,负责执行方法执行后的内容:
package com.itholmes.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
//returnValue:使用AfterReturningAdvice是可以拿到一个returnValue返回值的。
//其他的参数和BeforeAdvice中的before参数一样。
@Override
public void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println(“执行了”+method.getName()+“方法,返回结构为:”+returnValue);
}
}
UserService接口:
package com.itholmes.service;
public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}
UserServiceImpl实现类:
package com.itholmes.service;
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println(“增加了一个用户”);
}
@Override
public void delete() {
System.out.println(“删除了一个用户”);
}
@Override
public void update() {
System.out.println(“更新了一个用户”);
}
@Override
public void select() {
System.out.println(“查询了一个用户”);
}
}
再往后,先在xml文件中,注册bean,然后通过xml方式来指定aop的相关内容了。
创建applicationContext.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: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
https://www.springframework.org/schema/aop/spring-aop.xsd">
aop:config
<aop:pointcut id=“pointcut” expression=“execution(* com.itholmes.service.UserServiceImpl.*(…))”></aop:pointcut>
<aop:advisor advice-ref=“log” pointcut-ref=“pointcut”/>
<aop:advisor advice-ref=“afterLog” pointcut-ref=“pointcut”/>
</aop:config>
最后,我们测试一下mytest类:
import com.itholmes.service.UserService;
import com.itholmes.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
//注意:AOP实现原理是动态代理,而动态代理代理的是接口,因此在这我们只能写接口类型。
UserService userService = (UserService) context.getBean(“userService”);
userService.add();
}
}
==================================================================================
先说一下execution()方法参数的含义。
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
-
execution(): 表达式主体。
-
第一个*号:表示返回类型,*号表示所有的类型。
-
包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
-
第二个*号:表示类名,*号表示所有的类。
-
*(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
这些参数理解了才更容易理解AOP。
8. 实现aop(二) 自定义类方式 (围绕自定义类,也就是切面(aspect)定义来实现)
============================================================================================================
测试类,接口,接口实现类不变。
首先,创建一个自定义类:
package com.itholmes.diy;
public class DiyPointCut {
public void before(){
System.out.println(“------方法执行前-------”);
}
public void after(){
System.out.println(“-------方法执行后--------”);
}
}
**xml配置文件来进行配置:
其实就是换了aop:aspect来操作而已:**
<?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”
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
aop:config
<aop:aspect ref=“diy”>
<aop:pointcut id=“point” expression=“execution(* com.itholmes.service.UserServiceImpl.*(…))”/>
<aop:before method=“before” pointcut-ref=“point”/>
<aop:after method=“after” pointcut-ref=“point”/>
</aop:aspect>
</aop:config>
=================================================================================
接口,实现类,测试类不变。
设置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”
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
https://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy proxy-target-class=“false”/>
定义一个AnnotationPointCut,在里面设置注解信息。
package com.itholmes.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//方式三:使用注解来实现AOP方式
//标注:这个类是一个切面
@Aspect
public class AnnotationPointCut {
//这里要注意一下,在junit中也有一个@Before注解,不要导错了。
@Before(“execution(* com.itholmes.service.UserServiceImpl.*(…))”)
public void before(){
System.out.println(“--------方法执行前”);
}
//同样不要到错包。
@After(“execution(* com.itholmes.service.UserServiceImpl.*(…))”)
public void after(){
System.out.println(“--------方法执行后”);
}
//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点。
//joinPoint就是效果图中的连接点
@Around(“execution(* com.itholmes.service.UserServiceImpl.*(…))”)
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(“环绕前”);
Signature signature = joinPoint.getSignature();//获得签名
//System.out.println(“signature:”+signature);
//执行方法
Object proceed = joinPoint.proceed();
System.out.println(“环绕后”);
}
//注意这个执行顺序,执行谁后执行谁!
//环绕前
//--------方法执行前
//增加了一个用户
//环绕后
//--------方法执行后
}
三种实现AOP效果都一样,后两者简便一些。
=======================================================================================
Spring整体效果图如下,而JDBC Template是属于蓝色部分的内容:
Spring框架对JDBC进行了封装,使用JdbcTemplate方便实现对数据库操作。
第一步,导入jar包:
首先,引入jar包:(该用maven依赖的依赖,不会maven该导包的导包。)
<?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”>
4.0.0
org.example
spring5_atguigu_demo05
1.0-SNAPSHOT
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
org.springframework
spring-webmvc
5.3.13
mysql
mysql-connector-java
8.0.22
com.alibaba
druid
1.1.9
org.springframework
spring-jdbc
5.2.6.RELEASE
org.springframework
spring-tx
5.2.6.RELEASE
org.springframework
spring-orm
5.2.6.RELEASE
第二步,在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/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.itholmes.spring5.*”/>
第三步,创建对应jdbcTemplate的对象,将dataSource(第二步,配置的信息)注入里面:
<?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/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.itholmes.spring5.*”/>
第四步,创建service类,创建dao类,在dao注入jdbcTemplate对象(算是实操):
在beans.xml配置文件中添加组件扫描:
<context:component-scan base-package=“com.itholmes.spring5”/>
测试类Test:
/*
概述:
@Date:Create in 15:32 2021/12/31
*/
import com.itholmes.spring5.bean.Book;
import com.itholmes.spring5.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestBook {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(“beans1.xml”);
BookService service = context.getBean(“bookService”, BookService.class);
Book book = new Book();
book.setBook_name(“张三”);
book.setBook_password(“zhangsan”);
service.addBook(book);
}
}
=====================================================================================
增删改的操作,都是调用jdbcTemplate对象中的update方法,主要的查询有多种不同的返回值和方式!
bean的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: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/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.itholmes.spring5.*”/>
Book实体类:
package com.itholmes.spring5.bean;
public class Book {
private int user_id;
private String user_name;
private String user_password;
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
@Override
public String toString() {
return “Book{” +
“user_id=” + user_id +
“, user_name='” + user_name + ‘’’ +
“, user_password='” + user_password + ‘’’ +
‘}’;
}
}
BookDao层的接口:
package com.itholmes.spring5.dao;
import com.itholmes.spring5.bean.Book;
import java.util.List;
public interface BookDao {
public void add(Book book);
public void update(Book book);
public void delete(String id);
public int selectCount();
public Book findBookInfo(String id);
public List findBookList();
}
实现BookDao接口的实现类(重点,多看查询操作是怎么完成的):
package com.itholmes.spring5.dao;
import com.itholmes.spring5.bean.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class BookDaoImpl implements BookDao{
//注入jdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
//添加操作
@Override
public void add(Book book) {
String sql = “insert into user
(user_name
,user_password
)values(?,?)”;
//重点:jdbcTemplate中可以通过update方法来实现添加操作。
//update方法有两个参数:
//第一个参数:String sql 是sql语句
//第二个参数:Object… args(可变参数,也可以添加数组!) 是sql语句我们需要传入?参数,这个就是我们要传入的不同类型的值。
//int update = jdbcTemplate.update(sql, book.getBook_name(), book.getBook_password());
//因为args是一个可变参数,我们也可以添加个数组啥的。
Object[] args = {book.getUser_name(), book.getUser_password()};
int update = jdbcTemplate.update(sql, args);
System.out.println(update);
}
//修改方法
@Override
public void update(Book book) {
String sql = “update user
set user_name=?,user_password=? where user_id=?”;
Object[] args = {book.getUser_name(),book.getUser_password(),book.getUser_id()};
int update = jdbcTemplate.update(sql, args);
System.out.println(update);
}
//删除方法
@Override
public void delete(String id) {
String sql = “delete from user
where user_id=?”;
int update = jdbcTemplate.update(sql, id);
独家面经总结,超级精彩
本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!
Java面试准备
准确的说这里又分为两部分:
- Java刷题
- 算法刷题
Java刷题:此份文档详细记录了千道面试题与详解;
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
e.Repository;
import java.util.List;
@Repository
public class BookDaoImpl implements BookDao{
//注入jdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
//添加操作
@Override
public void add(Book book) {
String sql = “insert into user
(user_name
,user_password
)values(?,?)”;
//重点:jdbcTemplate中可以通过update方法来实现添加操作。
//update方法有两个参数:
//第一个参数:String sql 是sql语句
//第二个参数:Object… args(可变参数,也可以添加数组!) 是sql语句我们需要传入?参数,这个就是我们要传入的不同类型的值。
//int update = jdbcTemplate.update(sql, book.getBook_name(), book.getBook_password());
//因为args是一个可变参数,我们也可以添加个数组啥的。
Object[] args = {book.getUser_name(), book.getUser_password()};
int update = jdbcTemplate.update(sql, args);
System.out.println(update);
}
//修改方法
@Override
public void update(Book book) {
String sql = “update user
set user_name=?,user_password=? where user_id=?”;
Object[] args = {book.getUser_name(),book.getUser_password(),book.getUser_id()};
int update = jdbcTemplate.update(sql, args);
System.out.println(update);
}
//删除方法
@Override
public void delete(String id) {
String sql = “delete from user
where user_id=?”;
int update = jdbcTemplate.update(sql, id);
独家面经总结,超级精彩
本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!
[外链图片转存中…(img-4cUBVP2h-1714753869999)]
[外链图片转存中…(img-YUlVL1Nr-1714753869999)]
[外链图片转存中…(img-FUR86ap7-1714753869999)]
[外链图片转存中…(img-6wwfiw0E-1714753870000)]
Java面试准备
准确的说这里又分为两部分:
- Java刷题
- 算法刷题
Java刷题:此份文档详细记录了千道面试题与详解;
[外链图片转存中…(img-kbp6Foiz-1714753870000)]
[外链图片转存中…(img-188DGASF-1714753870000)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!