spring 入门学习笔记
spring 入门学习笔记[1]
入门笔记,尚未学习完,后续进行补充。
新手上路,望斧正
1 简介
spring 理念:使现有技术更加容易使用,本身是一个大杂烩,整合了现有框架。
ssh: struct2+spring+hibernate
ssm:springmvc+spring+mybatis
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.13</version>
</dependency>
优点
spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架。
2 IOC 理论
2.1 IOC初步体会
当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能的独立于其他的 Java 类来增加这些类可重用可能性,当进行单元测试时,可以使它们独立于其他类进行测试。依赖注入(或者有时被称为配线)有助于将这些类粘合在一起,并且在同一时间让它们保持独立。
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
使用一个set 的接口,让程序不再具有主动性,而是变成被动的接收对象。程序不再去管理对象的创建,系统耦合性降低,可以更加专注在业务上实现
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="UserDao" class="com.fadaiyu.dao.UserDaoImpl">
<!-- collaborators and configuration for this bean go here -->
<property name="str" value="spring"/>
</bean>
<bean id="UserDaoMysqlImpl" class="com.fadaiyu.dao.UserDaoMysqlImpl"/>
<bean id="UserServiceImpl" class="com.fadaiyu.service.UserServiceImpl">
<!--
ref 引用spring 容器中创建的对象
value 是引用具体的值
-->
<property name="userDao" ref="UserDaoMysqlImpl"/>
</bean>
<!-- more bean definitions go here -->
</beans>
//拿到ApplicationContext 拿到spring 容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//直接获取一个bean
UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
userServiceImpl.getUser();
程序不需要再new 一个对象,而是由spring 进行创建管理装配。至于想用那种UserDao的实现方式,仅需要修改一配置文件即可。如果添加更多的实现方式,只需要在配置文件中添加一个bean ,而代码无需改动。
2.2 IOC 创建对象的过程
在走到getBean的时候创建的对象。
spring 默认使用无参构造器,有参构造器见Core Technologies (spring.io)的1.4.1
2.3 set注入方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="Adress" class="com.fadaiyu.dao.Adress" name="adress">
<property name="address" value="china"/>
</bean>
<bean id="Student" class="com.fadaiyu.dao.Student" name="student">
<!--第一种,普通类型注入-->
<property name="name" value="fadaiyu"/>
<property name="adress" ref="Adress">
</property>
<!--数组-->
<property name="books">
<array>
<value>11111</value>
<value>22222</value>
</array>
</property>
<!--list 注入-->
<property name="hobbies">
<list>
<value>aaaaa</value>
<value>bbbbb</value>
</list>
</property>
<!--map-->
<property name="card">
<map>
<entry key="qqq" value="qqqq"/>
<entry key="www" value="www"/>
</map>
</property>
<property name="games">
<set>
<value>lol</value>
<value>cf</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="学号">77777</prop>
<prop key="pwd">123</prop>
</props>
</property>
</bean>
</beans>
2.4 p命名和c命名
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="User" class="com.fadaiyu.dao.User" p:name="fadaiyu" p:age="12"/>
<bean id="User2" class="com.fadaiyu.dao.User" c:age="17" c:name="fadaiyu2"/>
</beans>
**要导入相关依赖 **
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
2.5 作用域
2.6 bean 的自动装配
自动装配是spring满足bean依赖一种方式,spring会在上下文中自动寻找,并给bean装配属性。
spring 中有三种装配方式:
- 在xml 中配置I(即上面的方式)
- 在java 中显示配置
- 隐式的自动装配bean
<bean id="People" name="pople" class="com.fadaiyu.dao.People" autowire="byName">
<property name="name" value="fadaiyu"/>
</bean>
按属性名自动装配。Spring寻找与需要自动连接的属性同名的bean。需要保证id 唯一
<bean id="People" name="pople" class="com.fadaiyu.dao.People" autowire="byType">
<property name="name" value="fadaiyu"/>
</bean>
如果容器中恰好存在一个该属性类型的bean,则允许该属性被自动连接。
2.7 通过注解装配
导入依赖
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
在属性上加上 @Autowired,可以配合@qualifier(value=xxx)来指定唯一的bean对象注入。通过bytype 方式
@Resource
@Resource(name = "Dog")
private Dog dog;
通过byname 方式,如果找不到名字,再使用bytype
@Component
组件,放在类上,说明这个类被spring 管理了,就是bean
- dao [@Repository]
- service [@Service]
- controller [@Controller]
@Value
给属性注解,可以放在属性上,也可以放在set上
3 AOP
3.1静态代理
角色分析:
- 抽象角色:一般使用接口或者抽象类来解决。
- 真实角色:被代理的角色。
- 代理角色:代理真实角色,代理真实角色后一般会做一些附属操作。
- 客户:访问代理对象的人。
//租房
public interface Rent {
//出租房屋
public void rent();
}
//房东,是真实角色,它要出租房屋
public class LandLord implements Rent{
@Override
public void rent() {
System.out.println("房东出租房屋");
}
}
//中介
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TheMediation implements Rent{
private LandLord landLord;
@Override
public void rent() {
//帮助房东租房子
seeHose();
contract();
charge();
landLord.rent();
}
public void seeHose(){
System.out.println("看房");
}
public void contract(){
System.out.println("签合同");
}
public void charge(){
System.out.println("收费");
}
}
//要租房子的客户
public class Customer {
public static void main(String[] args) {
//房东要出租房子,将房子交给中介,房东只用提供房子,中介帮助房子完成其他操作
TheMediation mediation = new TheMediation(new LandLord());
//用户只用去找中介,不用直接面对房东
mediation.rent();
}
}
代理模式的好处:
- 可以让真实角色操作更加纯粹,不用去关注一些公共业务。
- 公共业务交给代理角色,实现业务分工。
- 公共业务发生扩展,方便集中管理。
3.2 动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理对象是动态生成的,不是直接写好的。
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口: jdk动态代理
- 基于类: cglib
- java 字节码:javasist
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target){
this.target=target;
}
//得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this );
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是使用反射机制实现
Object invoke = method.invoke(target, args);
return invoke;
}
}
public class Client {
public static void main(String[] args) {
//真实角色
UserServiceImpl userService=new UserServiceImpl();
//代理角色
ProxyInvocationHandler pih=new ProxyInvocationHandler();
//设置要代理的对象
pih.setTarget(userService);
//生成代理类 ##注意:动态代理,代理的是接口
UserService userProxy=(UserService)pih.getProxy();
userProxy.addUser();
}
}
动态代理的好处:一个动态代理类代理的是一个接口,一般就是对应的一类业务,一个动态代理可以代理多个类,只要是心啊了同一个接口。
3.3 aop 实现
添加依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
-
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
-
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
-
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
-
目标(Target):被通知对象。
-
代理(Proxy):向目标对象应用通知之后创建的对象。
-
切入点(PointCut):切面通知 执行的 “地点”的定义。
-
连接点(JointPoint):与切入点匹配的执行点。
3.3.1 使用原生的spring api
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="com.fadaiyu.service.UserServiceImpl"/>
<bean id="befoLog" class="com.fadaiyu.log.Log"/>
<bean id="afterLog" class="com.fadaiyu.log.AfterLog"/>
<!--方式一 使用原生的spring api-->
<!--配置aop-->
<aop:config>
<!--切入点:expression表达式:execution(要执行的位置,,,)-->
<aop:pointcut id="pointcut" expression="execution(* com.fadaiyu.service.UserServiceImpl.*(..))"/>
<!--执行环绕-->
<aop:advisor advice-ref="befoLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContex.xml");
// ## 注意 动态代理代理的是接口
UserService userService=context.getBean("userService",UserService.class);
userService.addUser();
}
3.3.2 自定义实现
<!--方法二;自定义类-->
<bean id="diypoint" class="com.fadaiyu.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面。 ref 要引用的类-->
<aop:aspect ref="diypoint">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.fadaiyu.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="beforePoint" pointcut-ref="point"/>
<aop:after method="afterPonit" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
3.3.3 使用注解实现
<!--方式三:开启注解支持, jdk(默认) cglib(proxy-target-class="true") -->
<aop:aspectj-autoproxy />
@Aspect //标注这个类是一个切面
public class AnnPoint {
@Before("execution(* com.fadaiyu.service.*.*(..))")
public void before(){
System.out.println("前------------");
}
@After("execution(* com.fadaiyu.service.*.*(..))")
public void after(){
System.out.println("------------后");
}
@Around("execution(* com.fadaiyu.service.*.*(..))")
public void around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("环绕前");
Object procced=pj.proceed();
System.out.println("环绕后");
}
}
4 整合mybatis
添加依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
配置过滤
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
spring 接管mybatis
<!--datasource 使用spring 的数据源替换mybatis的配置-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/myemployees?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<!--绑定mybatis 配置文件-->
<!-- <property name="configLocation" value="classpath:mybatis-config.xml"/>-->
<property name="mapperLocations" value="classpath:com/fadaiyu/mapper/*.xml"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入sqlSessionFactory,没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="jobsMapperImpl" class="com.fadaiyu.mapper.JobsMapperImpl">
<property name="sqlSessionTemplate" ref="sqlSession"/>
</bean>
也可以使用简化操作,继承SqlSessionDaoSupport
public class JobsMapperImpl2 extends SqlSessionDaoSupport implements JobsMapper{
@Override
public List<Jobs> selectAll() {
return getSqlSession().getMapper(JobsMapper.class).selectAll();
}
}
跟随B站 遇见狂神说 学习spring 的入门笔记。 ↩︎
本文作者:发呆鱼
本文链接:https://www.cnblogs.com/dyiblog/articles/15854039.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步