BeanFactory
,它是工厂模式的实现。BeanFactory
使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<?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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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:annotation-config/>
</beans>
bean的配置:bean就是java对象,由Spring创建和管理
<bean id="" name="" class=""></bean>
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
import:将多个配置文件,导入合并一个
<import resource="路径"/>
constructor-arg:通过构造函数注入
第一种根据index参数下标设置
<bean id="自定义" class="全限定路径类名">
<!-- index指构造方法参数顺序, 下标从0开始 -->
<constructor-arg index="0" value="属性值"/>
</bean>
第二种根据参数名字设置
<bean id="自定义" class="全限定路径类名">
<!-- name指参数名 -->
<constructor-arg name="参数名" value="属性值"/>
</bean>
第三种根据参数类型设置
<bean id="自定义" class="全限定路径类名">
<!--按着传值顺序赋值-->
<constructor-arg type="类型" value="属性值"/>
</bean>
property:通过setter对应的方法注入
<bean id="自定义" class="全限定路径类名">
<property name="属性名" value="属性值"/>
</bean>
<bean id="address" class="com.demo.domain.Address">
<property name="address" value="大竹"/>
</bean>
<bean id="student" class="com.demo.domain.Student">
<!--第一种,普通值注入,value-->
<property name="name" value="雷雪松"/>
<!--第二种,Bean注入,ref-->
<property name="address" ref="address"/>
<!--第三种,数组注入,array-->
<property name="books">
<array>
<value>红楼梦</value>
<value>三国演义</value>
<value>水浒传</value>
<value>西游记</value>
</array>
</property>
<!--第四种,List注入,list-->
<property name="hobbys">
<list>
<value>听歌</value>
<value>睡觉</value>
<value>敲代码</value>
</list>
</property>
<!--第五种,Map注入,map-->
<property name="card">
<map>
<entry key="身份证" value="12345678910987654321"/>
<entry key="电话号码" value="1314520"/>
</map>
</property>
<!--第六种,Set注入,set-->
<property name="games">
<set>
<value>LOL</value>
<value>DNF</value>
</set>
</property>
<!--第七种,null注入,null-->
<property name="wife">
<null/>
</property>
<!--第八种,Properties注入,props-->
<property name="info">
<props>
<prop key="学号">1861020336</prop>
</props>
</property>
</bean>
p 命名空间注入 : 注入属性的值:property
需要在头文件中加入约束文件
xmlns:p="http://www.springframework.org/schema/p"
c 命名空间注入 : 通过构造器注入:constructor-arg
需要在头文件中加入约束文件
xmlns:c="http://www.springframework.org/schema/c"
自动装配是Spring满足Bean的一种方式
Spring会在上下文中自动寻找,并自动给Bean装配属性
实现方式:
有三种装配方式:
byName:按名称自动装配
<bean id="自定义" class="实体类全限定名" autowire="byName">
<property name="属性" value="属性值"/>
</bean>
byType:按类型自定装配
<bean id="自定义" class="实体类全限定名" autowire="byType">
<property name="属性" value="属性值"/>
</bean>
导入约束:context
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
开启注解支持
<context:annotation-config/>
注解的前提是自动装配的属性在IOC容器中存在,且符合类型byType
使用前先导包
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
@Resource如有指定的name属性,先按该属性进行byName方式查找装配;
其次再进行默认的byName方式进行装配;
如果以上都不成功,则按byType的方式自动装配。
都不成功,则报异常
导入约束:aop
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/context/spring-aop.xsd
指定扫描的包
<context:component-scan base-package="被扫描的包名路径"/>
@Configuration
public class MyConfig {
@Bean
public Dog dog(){
return new Dog();
}
}
@Test
public void test1() {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Dog dog = context.getBean("dog", Dog.class);
System.out.println(dog);
}
抽象角色 : 一般使用接口或者抽象类来实现
真实角色 : 被代理的角色
代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .
客户 : 使用代理角色来进行一些操作
好处:
缺点 :
Object invoke(Object proxy, 方法 method, Object[] args);
//proxy - 调用该方法的代理实例
//method -所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object object;
public void setObject(Object object) {
this.object = object;
}
//生成得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果
//动态代理的的本质,就是使用反射机制实现
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object, args);
return result;
}
}
提供声明式事务;允许用户自定义切面
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
目标(Target):被通知对象。
代理(Proxy):向目标对象应用通知之后创建的对象。
切入点(PointCut):切面通知 执行的 “地点”的定义。
连接点(JointPoint):与切入点匹配的执行点。
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory
和至少一个数据映射器类
在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder
来创建 SqlSessionFactory
的。 而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean
来创建
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--获取数据源-->
<property name="dataSource" ref="datasource"/>
<!--绑定MyBatis配置文件-->
<property name="configLocations" value="classpath:MyBatis配置文件名称"/>
<!--绑定MyBatis映射文件-->
<property name="mapperLocations" value="classpath:映射文件的全限定名"/>
<!--别名-->
<property name="typeAliasesPackage" value="实体类包名"/>
</bean>
SqlSessionFactory
需要一个 DataSource
(数据源)
<!--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:///数据库名"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
SqlSessionTemplate
是 MyBatis-Spring 的核心。作为 SqlSession
的一个实现
<!--sqlSessionTemplate:就是我们使用得sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
创建一个接口实现类
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
Bean注入到IOC容器种
<bean id="userMapper" class="com.demo.mapper.Impl.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
步骤
导入约束
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
配置
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给那些方法配置事务-->
<!--配置事务的传播特性-->
<tx:attributes>
<!-- * 全部方法都执行-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务的切入-->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.demo.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>