首先想到的两大核心IOC和AOP.
耦合:泛指代码之间的依赖关系
解耦和的思路:解决了编译时期的异常
·例如:
当web层需要调用service层时,用到service层的对象中的方法,
如果service层还没有实现类那就没法创建对象了,所以可用多态接口来接受
反射创建实现类对象,将以上方法封装就是工厂,配置文件用key-value形式,
在工厂中,通过获取key就可以获取反射所需的实现类全限定名,
解析xml文件,将key和value存入map,考虑到线程安全和内存问题,在解析的同时,
直接通过反射一次性创建好所有实现类对象存入map即可
控制反转:ioc
包括依赖查找和依赖注入
工厂就是负责给我们从容器中获取指定对象的类
由工厂为我们查找或者创建对象
ApplicationContext
常用---ClassPathXmlApplicationContext(类路径)
FileSystemXmlApplicationContext(此盘路径)
执行流程
1创建容器
<bean id="UserService" class="cn.itcast.service.impl.UserServiceImpl" scope="" init-method="方法名" destroy-method="">
默认创建的对象时单实例的:所以在创建容器的时候会把所有的单实例对象全部创建放到容器中
对象的作用域Scope:
singleton,随着容器的创建而创建,随着容器的关闭而消失
prototype,一个请求创建一次,自动回收
request,
session
init-method:创建对象之后立即执行的方法
destroy-method:销毁对象前执行的方法
2了解创建对象的另外两种方法
--静态工厂:创建容器就会创建对象
<bean id="" class="工厂的全限定名" factory-method="工厂里的方法"></bean>
--普通工厂
<bean id="呵呵呵呵" class="工厂的全限定名"></bean>
<bean id="" factory-bean="呵呵呵呵" factory-method="工厂里的方法"></bean>
依赖注入:Dependency Injection
思路:
简单的说,通过控制反转,把对象的创建交给了 spring
而当代码之间的依赖的时候,就是坐等框架把持久层对象传入业务层
构造方法注入:
提供有参数的构造方法
当属性是array,list,set泛型时基本数据类型时可以通用
name:
index:
定位属性
value:给基本属性赋值
ref:给容器中的对象赋值
<constructor-arg name="name" value="小明">
<array>
<value> <value>
<value> <value>
</array>
</constructor-arg>
set方法注入
当属性是array,list,set泛型时基本数据类型时可以通用
name属性要写set方法后的部分第一个字母要小写
<property name="name" value="xixi" ref=""></property>
基于注解的 IOC 配置
用注解首先要开启包扫描
<context:component-scan base-package="cn.itcast"></context:component-scan>
创建对象注解
@Component(value="")
默认创建的唯一标识是当前类的类名首字母小写
可利用value属性指定唯一标识
@Controller
@Service
@Repository
依赖注入注解
@Autowired:
自动按照类型注入。和唯一标识没有关系,
当使用注解注入属性时,set方法可以省略
@Autowired
private AccountDao accountDao1;
举例:自动在容器中寻找实现了这个接口类型的实现类,找到两个会报错,
所以可以用属性名进一步作为标识在容器中寻找
@Repository accountDao1
AccountDaoImpl()
@Repository accountDao2
AccountDaoImpl()
@Qualifier(value="")-------除了用在属性上也可以用在方法参数上
可以结合@Autowired指定唯一标识
@Resource(name="accountDao")这是jdk提供的注解,name可以指定唯一标识
属性的注入利用的是暴力反射注入优先寻找jdk注解
@value(value="")
一:注入基本数据类型和 String 类型数据的
二:注入被spring管理的properties文件中的内容
1将文件给容器管理这个类是加载
<bean id="properties" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
//给属性赋值
<property name="location" value="classpath:jdbc.properties"></property>
</bean>
2@value(value="${}")//结合el表达式
对象的作用域的注解
@Scope(value="")//singlton prototype
@PostConstruct :用在方法上创建对象之后立刻执行的方法
@PreDestroy :用在方法上销毁对象之前执行的方法
============纯注解编程:把配置文件用类来代替
@Configuration():声明一个配置类,创建容器时会从该类上加载注
属性: value:用于指定配置类的字节码
@ComponentScan(basePackages= {})用于指定要扫描的包创建容器时自动扫描配置了注解的类
@Bean(name=""):给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。
该注解只能写在方法上,表明使用此方法返回值创建一个对象,并且放入 spring 容器
@PropertySource (value={}) 用于加载.properties 文件中的配置
value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
@Import(value=.class) 用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 写上也没问题
小技巧:1当包扫描能扫描到的时候,类上可以不用写Configuration
2spring 配置类是创建容器的参数时,也可以不用写Configuration
junit测试结合spring
思路:注解要运行在spring容器中,所以替换掉原junit它的运行器,需要依靠 spring 框架,
因为它提供了一个运行器,可以读取配置文件(或注解)来创建容器。我们只需要告诉它配置文件在哪就行了。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration 指定 spring 配置文件的位置
locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明
classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。