1、为什么 Spring 依靠一个注解 @Autowired 就可以实现对象的初始化?
- 这是因为在 Spring 容器启动的时候,会加载配置信息(如 XML 文件、注解或 Java 配置类)。扫描指定包的路径,查找带有
@Component、@Service、@Repository、@Controller等注解的类,将这些类注册为 Bean;例如@Configuration注解的类会被解析为配置类,@Bean注解的方法会生成 - 随后,使用反射机制创建 Bean 的实例,BeanFactory 工厂类
- 使用
@Autowired注解的时候,会自动注入对象实例,这样就不用每次new xxx()了,解耦代码,实现高效的开发
2、Spring的面向切面编程是什么?AOP
在 java 系统开发中,最重要的就是业务代码逻辑,其中可能会包含复杂代码。如果我们需要修改代码的话,可以通过AOP的配置来进行代码流程的修改,比如在调用某个函数之前再做一下其他的准备工作,在调用完之后,方法增强做其他的结尾工作。
举例代码:
定义目标类
package tech.pdai.springframework.service;
/**
* @author pdai
*/
public class AopDemoServiceImpl {
public void doMethod1() {
System.out.println("AopDemoServiceImpl.doMethod1()");
}
public String doMethod2() {
System.out.println("AopDemoServiceImpl.doMethod2()");
return "hello world";
}
public String doMethod3() throws Exception {
System.out.println("AopDemoServiceImpl.doMethod3()");
throw new Exception("some exception");
}
}
定义切面类
package tech.pdai.springframework.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* @author pdai
*/
public class LogAspect {
/**
* 环绕通知.
*
* @param pjp pjp
* @return obj
* @throws Throwable exception
*/
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("-----------------------");
System.out.println("环绕通知: 进入方法");
Object o = pjp.proceed();
System.out.println("环绕通知: 退出方法");
return o;
}
/**
* 前置通知.
*/
public void doBefore() {
System.out.println("前置通知");
}
/**
* 后置通知.
*
* @param result return val
*/
public void doAfterReturning(String result) {
System.out.println("后置通知, 返回值: " + result);
}
/**
* 异常通知.
*
* @param e exception
*/
public void doAfterThrowing(Exception e) {
System.out.println("异常通知, 异常: " + e.getMessage());
}
/**
* 最终通知.
*/
public void doAfter() {
System.out.println("最终通知");
}
}
xml 配置 AOP
<?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="tech.pdai.springframework" />
<aop:aspectj-autoproxy/>
<!-- 目标类 -->
<bean id="demoService" class="tech.pdai.springframework.service.AopDemoServiceImpl">
<!-- configure properties of bean here as normal -->
</bean>
<!-- 切面 -->
<bean id="logAspect" class="tech.pdai.springframework.aspect.LogAspect">
<!-- configure properties of aspect here as normal -->
</bean>
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="logAspect">
<!-- 配置切入点 -->
<aop:pointcut id="pointCutMethod" expression="execution(* tech.pdai.springframework.service.*.*(..))"/>
<!-- 环绕通知 -->
<aop:around method="doAround" pointcut-ref="pointCutMethod"/>
<!-- 前置通知 -->
<aop:before method="doBefore" pointcut-ref="pointCutMethod"/>
<!-- 后置通知;returning属性:用于设置后置通知的第二个参数的名称,类型是Object -->
<aop:after-returning method="doAfterReturning" pointcut-ref="pointCutMethod" returning="result"/>
<!-- 异常通知:如果没有异常,将不会执行增强;throwing属性:用于设置通知第二个参数的的名称、类型-->
<aop:after-throwing method="doAfterThrowing" pointcut-ref="pointCutMethod" throwing="e"/>
<!-- 最终通知 -->
<aop:after method="doAfter" pointcut-ref="pointCutMethod"/>
</aop:aspect>
</aop:config>
<!-- more bean definitions for data access objects go here -->
</beans>
测试类
/**
* main interfaces.
*
* @param args args
*/
public static void main(String[] args) {
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("aspects.xml");
// retrieve configured instance
AopDemoServiceImpl service = context.getBean("demoService", AopDemoServiceImpl.class);
// use configured instance
service.doMethod1();
service.doMethod2();
try {
service.doMethod3();
} catch (Exception e) {
// e.printStackTrace();
}
}
输出结果
-----------------------
环绕通知: 进入方法
前置通知
AopDemoServiceImpl.doMethod1()
环绕通知: 退出方法
最终通知
-----------------------
环绕通知: 进入方法
前置通知
AopDemoServiceImpl.doMethod2()
环绕通知: 退出方法
最终通知
后置通知, 返回值: hello world
-----------------------
环绕通知: 进入方法
前置通知
AopDemoServiceImpl.doMethod3()
最终通知
异常通知, 异常: some exception
Redis
五种数据结构:

String
import redis.clients.jedis.Jedis;
public class RedisStringExample {
public static void main(String[] args) {
// 连接到 Redis 服务器
Jedis jedis = new Jedis("localhost", 6379);
System.out.println("连接成功");
// 设置键值对
jedis.set("key1", "value1");
System.out.println("设置键值对成功: " + jedis.get("key1")); // value1
// 增加数值
jedis.set("counter", "100");
System.out.println("增加前: " + jedis.get("counter")); // 100
jedis.incr("counter");
System.out.println("增加后: " + jedis.get("counter")); // 101
// 关闭连接
jedis.close();
}
}
Hash
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.Map;
public class RedisHashExample {
public static void main(String[] args) {
// 连接到 Redis 服务器
Jedis jedis = new Jedis("localhost", 6379);
System.out.println("连接成功");
// 设置哈希值
Map<String, String> user = new HashMap<>();
user.put("name", "Alice");
user.put("age", "30");
user.put("email", "alice@example.com");
jedis.hmset("user:1", user);
System.out.println("设置哈希值成功");
// 获取哈希值
System.out.println("获取哈希值: " + jedis.hgetAll("user:1")); // 获取哈希值: {name=Alice, age=30, email=alice@example.com}
// 删除哈希字段
jedis.hdel("user:1", "email");
System.out.println("删除后: " + jedis.hgetAll("user:1")); // 删除后: {name=Alice, age=30}
// 关闭连接
jedis.close();
}
}
列表(List)
import redis.clients.jedis.Jedis;
public class RedisListExample {
public static void main(String[] args) {
// 连接到 Redis 服务器
Jedis jedis = new Jedis("localhost", 6379);
System.out.println("连接成功");
// 添加列表元素
jedis.lpush("list1", "item1");
jedis.lpush("list1", "item2");
jedis.rpush("list1", "item3");
System.out.println("添加列表元素成功: " + jedis.lrange("list1", 0, -1)); // 添加列表元素成功: [item2, item1, item3]
// 获取列表长度
System.out.println("列表长度: " + jedis.llen("list1")); // 列表长度: 3
// 弹出列表元素
System.out.println("左弹出: " + jedis.lpop("list1")); // 左弹出: item2
System.out.println("右弹出: " + jedis.rpop("list1")); // 右弹出: item3
// 关闭连接
jedis.close();
}
}
集合(Set)
import redis.clients.jedis.Jedis;
public class RedisSetExample {
public static void main(String[] args) {
// 连接到 Redis 服务器
Jedis jedis = new Jedis("localhost", 6379);
System.out.println("连接成功");
// 添加集合元素
jedis.sadd("set1", "item1");
jedis.sadd("set1", "item2");
jedis.sadd("set1", "item3");
System.out.println("添加集合元素成功: " + jedis.smembers("set1")); // 添加集合元素成功: [item1, item2, item3]
// 检查元素是否存在
System.out.println("item1 是否存在: " + jedis.sismember("set1", "item1")); // item1 是否存在: true
// 删除集合元素
jedis.srem("set1", "item2");
System.out.println("删除后: " + jedis.smembers("set1")); // 删除后: [item1, item3]
// 关闭连接
jedis.close();
}
}
有序集合(Sorted Set)
import redis.clients.jedis.Jedis;
public class RedisSortedSetExample {
public static void main(String[] args) {
// 连接到 Redis 服务器
Jedis jedis = new Jedis("localhost", 6379);
System.out.println("连接成功");
// 添加有序集合元素
jedis.zadd("sortedSet1", 1.0, "item1");
jedis.zadd("sortedSet1", 2.0, "item2");
jedis.zadd("sortedSet1", 3.0, "item3");
System.out.println("添加有序集合元素成功: " + jedis.zrange("sortedSet1", 0, -1)); // 添加有序集合元素成功: [item1, item2, item3]
// 获取元素的分数
System.out.println("item2 的分数: " + jedis.zscore("sortedSet1", "item2")); // item2 的分数: 2.0
// 删除有序集合元素
jedis.zrem("sortedSet1", "item2");
System.out.println("删除后: " + jedis.zrange("sortedSet1", 0, -1)); // 删除后: [item1, item3]
// 关闭连接
jedis.close();
}
}
浙公网安备 33010602011771号