Maven
安装Maven,搭建环境变量
Maven获取jar包通过坐标定位:公司/组织(groupId)+项目名(artifactId)+版本(version)
Maven仓库分为:
本地:自己的
<localRepository>路径 </localRepository>
私有:有的公司自己搭建自己的仓库
中央:默认国外,可以改成阿里的比较快
3层保险,默认中央仓库首选为阿里云,如果失败去外国仓库1找,还失败去外国2仓库找;
中央仓库配置:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>nexus-aliyun</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<mirror>
<id>central</id>
<mirrorOf>central</mirrorOf>
<name>Maven Repository Switchbord</name>
<url>http://repo1.maven.org/maven2/</url>
</mirror>
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name For this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
**
IOC基础使用篇
**
ioc XML配置
最基础配置
--文件spring-ioc.xml中配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xxxx很多乱起八糟的东西>
<!--设置Bean的别名-->
<bean>class="包路径" id="类名(首字母一般小写)"</bean>
</beans>
//在调用处
ApplicationContext ioc=new ClassPathXmlApplicationContext("spring-ioc.xml");
ioc.getBean("user");
ioc.getBean(User.class);
ioc.getBean("user",User.class);
//获取bean
xml详解
<!--文件spring-ioc.xml中配置-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xxxx很多乱起八糟的东西>
<bean>class="包路径" id="类名(首字母一般小写)"</bean>
<description>用来描述一个Bean是干嘛的</description>
</beans>
使用import可以导入其他spring的xml配置文件
<import resource="spring-ioc2.xml"></import>-->
设置Bean的别名
用alias和那么两种方式可以设置别名,name可以设置很多别名,可以用空格,逗号,分号隔开
<alias name="user" alias="xxxx"></alias>
<bean>class="包路径" id="类名(首字母一般小写)" name="别名1 别名2,别名3;"</bean>
依赖注入
基于set方法:
基于set方法的名字对应的是id;setId那么名字是id,如果名字setIdxx那么就是idxx并不是上面那个属性名;
<bean class="cn.xxxx.beans.User" id="user6">
<property name="id" value="1"></property>
<property name="username" value="小名"></property>
<property name="realname" value="真名"></property>
</bean>
基于构造方法:
必须是有参构造函数
public User(Integer id, String username, String realname) {
this.id = id;
this.username = username;
this.realname = realname;
}
有三种排序方式
<!--**********************************第一种最好*******************************************-->
<!--最正常做法-->
<bean class="cn.xxxx.beans.User" id="user7">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="username" value="小名"></constructor-arg>
<constructor-arg name="realname" value="真名"></constructor-arg>
</bean>
<!--**********************************第二种不知道也没关系******************************************-->
<!--有参构造里面的name是可以省略的,如果省略name,那么参数顺序不能错乱-->
<bean class="cn.xxxx.beans.User" id="user7">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="小名"></constructor-arg>
<constructor-arg value="真名"></constructor-arg>
</bean>
<!--**********************************第三种不知道也没关系******************************************-->
<!--可以用index来排序-->
<bean class="cn.xxxx.beans.User" id="user7">
<constructor-arg index="2" value="真名"></constructor-arg>
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="小名"></constructor-arg>
</bean>
复杂数据类型依赖注入
public class Person implements InitializingBean,DisposableBean {
private Integer id;
private String name;
private String gender;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> course;
private Wife wife;
//get和set太多了省略掉,知道有就行
}
public class Wife {
private Integer age;
private String name;
//get和set太多了省略掉,知道有就行
}
基础型依赖注入
<bean class="cn.xxxx.beans.Person" id="person">
<property name="id" value="1"></property>
<property name="name" value="名字"></property>
<property name="gender" value=""></property>
<!--引用外部Bean <property name="wife" ref="wife"></property>-->
<!--使用内部bean 依赖注入其他bean -->
<property name="wife">
<bean class="cn.xxxx.beans.Wife">
<property name="age" value="24"></property>
<property name="name" value="地理"></property>
</bean>
</property>
<!--list 注入:如果泛型是基本数据类型<value>如果泛型是bean <bean>-->
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
</list>
</property>
<!--map 注入如果value是基本数据类型<entry key="1" value="Java"></entry>
如果value是bean value-ref-->
<property name="course">
<map>
<entry key="1" value="Java"></entry>
<entry key="2" value="数据库"></entry>
</map>
</property>
</bean>
p命名空间依赖注入
不支持集合,跟上面一样混用即可
<bean class="cn.xxxx.beans.Wife" id="wife" p:age="24" p:name="小行星">
</bean>
<bean class="cn.xxxx.beans.Person" id="person2" p:wife-ref="wife2" >
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
</list>
</property>
</bean>
c命名空间依赖注入,加有参构造函数
public Wife(Integer age, String name) {
this.age = age;
this.name = name;
}
<!--依然不支持集合的使用-->
<bean class="cn.xxxx.beans.Wife" id="wife2" c:age="2" c:name="xxx">
<!--<constructor-arg></constructor-arg>-->
</bean>
**
IOC高级使用篇
加载顺序:depends-on:控制bean加载顺序 当一个bean想让另一bean在它之前加载可以设置depends-on
**
<bean class="cn.xxxx.beans.User" id="user" depends-on="wife"></bean>
<bean class="cn.xxxx.beans.Wife" id="wife"></bean>
懒加载 设置后就不会在spring容器加载的时候 加载该bean 而是在使用的时候才会加载该bean
<bean class="cn.xxxx.beans.Wife" id="wife" lazy-init="true"></bean>
作用域scope
默认值: singleton 同一个id始终只会创建一次bean
prototype 多例(原型) 每一次使用都会创建一个bean
<bean class="cn.xxxx.beans.Person" id="person" scope="prototype" ></bean>
使用静态工厂来实例化bean
实例化bean默认使用无参构造函数,当我们创建了有参构造函数,那默认就使用有参构造函数
我们可以用静态工厂来干预这个过程
在person类中添加静态方法
public class Child extends Person {
}
public static Person createPersonFactory(){
Child child = new Child();
child.setName("儿子");
return child;
}
@Test
public void test04() {
Person person = ioc.getBean("person", Person.class);
System.out.println(person);
}
使用静态工厂方法实例化Bean,那么实例化出来的就是那个Child里面设置的值;
<bean class="cn.xxxx.beans.Person" id="person" factory-method="createPersonFactory" > </bean>
使用实例工厂方法实例化,跟上面的效果一样,只是不是静态方法的
public class PersonFacotry {
public Person createPersonFacotryMethod() {
Child child = new Child();
child.setName("儿子");
return child;
}
}
<bean class="cn.xxxx.beans.PersonFacotry" id="personFacotry"></bean>
<bean class="cn.xxxx.beans.Person" id="person"
factory-bean="personFacotry"
factory-method="createPersonFacotryMethod" >
</bean>
自动注入(非常重要)
autowire
byType:根据类型自动注入,如果出现两个wife那么直接就报错了
byName:根据set的方法名字自动去匹配
<bean class="cn.xxxx.beans.Person" id="person" autowire="byType" ></bean>
<bean class="cn.xxxx.beans.Wife" id="wife" autowire-candidate="false">
<property name="name" value="小A"></property>
</bean>
<bean class="cn.xxxx.beans.Wife" id="wife2" >
<property name="name" value="小B"></property>
</bean>
constructor:根据构造器去匹配,假如参数的名字没有匹配到,会根据类型去匹配,找到多个类型还是会注入失败,但是不会报错;
当根据类型匹配,有多个;
解决方案:
1、autowire-candidate:不参与自动注入
2、primary=“true”;自动注入以我为主
根据这个构造器去匹配,匹配到小B;
ioc容器里面bean必须足够构造函数里面的参数,如果有一个匹配不上那么就无法注入,少一个都不行,根据构造函数注入,将会是一个完整的注入;
public Person(Wife wife2) {
this.wife = wife2;
}
生命周期的回调
概念:ioc容器控制bean的生命周期,怎么感知到bean的生命周期;
有三种方式:
1、实现接口InitializingBean(初始化),DisposableBean(销毁)
public class Person implements InitializingBean,DisposableBean {}
// 实例化
public void afterPropertiesSet() throws Exception {//InitializingBean
System.out.println("实例化Person1");
}
// 销毁
public void destroy() throws Exception {//DisposableBean
System.out.println("销毁Person1");
}
//当我们创建这个实例的时候就会调用上面实例化方法
Person person = ioc.getBean("person", Person.class);
System.out.println(person);
//当我强制关闭ioc,自然的就会销毁
ioc.close();
2、自定义init()和destory()方法
通过配置在xml中方法,然后再在要配置的类中写上相应的方法就可以了
<bean class="cn.tulingxueyuan.beans.Person" id="person" init-method="initByConfig" destroy-method="destroyByConfig"></bean>
// 实例化
public void initByConfig() throws Exception {
System.out.println("实例化Person2");
}
// 销毁
public void destroyByConfig() throws Exception {
System.out.println("销毁Person2");
}
3、注解先放一放
spring创建第三方bean对象
<!--配置第三方bean跟我们上面的一样没啥好说的-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="username" value="${mysql.username}"></property>
<property name="password" value="${mysql.password}"></property>
<property name="url" value="${mysql.url}"></property>
<property name="driverClassName" value="${mysql.driverClassName}"></property>
</bean>
<!--db.properties是我们配置文件直接这样就可以引入了-->
<context:property-placeholder location="db.properties"></context:property-placeholder>