一、为什么要学习Spring?
①首先,Spring实现了最大程度的简化了开发过程,同时,Spring也是后续SpringMVC、SpringSSM、SpringBoot、SpringCloud的基础,在这些版本甚至是之后的技术,都是以努力简化开发流程所需要的繁琐步骤为核心。可以说基本上除了业务逻辑以外的事情,JAVA开发人员都可以讲事情交给Spring替你管理,这样便节约了大量的开发时间。
②妈耶,假设你原本敲代码需要一个月,现在有个技术,动动手你就能剩下千百行代码,只需要不到半个月就能完成你想要的功能,那么,你不心动嘛?这可是目前市面上大量开发公司都在用的哦!
二、学习Spring之前我们先学习一个核心思想IOC/DI。
(一)IOC(控制反转)/DI(依赖注入)
①IOD与DI
IOC全称Inversion of Control,翻译过来就是控制反转,这并不是什么技术,而是一种设计思想。什么意思呢?举个例子,以前我们写一个类,如果需要使用另一个类中的方法,那么我们会做什么?没错我们会选择 new 一个对象,也就是手动创建一个对象,并且这个对象的生死及使用都是由我们目前所在类所进行管理。IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制,也就是说现在有了IOC,你所需要的对象不是由你主动去创建,而是由IOC创建并管理分配给你,也就是控制权反过来了。这便是我们所说的控制反转。
DI全称Dependency Injection,翻译过来就是依赖注入,这跟IOC其实是一个东西,只是理解方式不一样,DI的理解方式不同于IOC,DI所诠释的是,当我们所在的类被创建出来的时候,Spring就会根据配置对象的属性把你所需要的那个类对象注入给你,并不涉及什么控制不控制。
三、Spring配置实现一个简易的IOC/DI。
①创建一个Maven项目。
我这里选择什么都不选,直接next创建项目。
②然后创建好工程后,在pom.xml导入Spring依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
</dependencies>
上面这步必须执行,不然没有下面的文件↑
③更改Languag level版本(我这里先用8)
File->Project.....
修改为8:
然后Apply->OK
④然后我们选择右键resources目录,new->XMLConfigurationFile->Spring Config
官方推荐名字: applicationContext.xml
公司使用名字: beans.xml
⑤我们去创建一个实体类:
创建一个实体类,右键java->new->JavaClass
然后现状:
⑥编译实体类(看看就好,下面用注解偷懒):
添加Get、Set方法,重写equals,hashCode、toString方法
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(username, user.username) &&
Objects.equals(password, user.password);
}
@Override
public int hashCode() {
return Objects.hash(username, password);
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
你看,写个实体类这些代码那么多,你不烦?我看着都烦诶,那么我们来偷懒吧!
偷懒第一步:添加一个lombok依赖到pom.xml的dependencies中
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>compile</scope>
</dependency>
偷懒第二步:回到实体类添加注解替换掉那一长串代码
import lombok.*;
@Data //替换get、set方法
@AllArgsConstructor //全参构造方法
@NoArgsConstructor //无参数构造方法
@EqualsAndHashCode //equals和hashCode方法
@ToString //toString方法
public class User {
private String username;
private String password;
}
然后我们在新建一个新的实体类Order,然后实体类中将User当成属性交给Order:
import lombok.*;
@Data //替换get、set方法
@AllArgsConstructor //全参构造方法
@NoArgsConstructor //无参数构造方法
@EqualsAndHashCode //equals和hashCode方法
@ToString //toString方法
public class Order {
private User user;
private String OrderName;
}
OK,偷懒完成,这便是注解开发带来的遍历,所以接下来可以想象一下SpringBoot的全注解开发能多省事儿?
⑦生成一个User对象和Order对象给Spring管理并配置注入User对象属性:
<!-- 一个bean就相当于新建了一个实体类的对象然后将这个对象交给Spring进行管理 -->
<!-- 而其中的property标签既是给你对应的属性注入了你想要的东西 -->
<bean id="zxy" class="com.test.entity.User">
<property name="username" value="张三"/>
<property name="password" value="123456"/>
</bean>
<bean id="order1" class="com.test.entity.Order">
<property name="orderName" value="订单一号"/>
<!-- 将实体类User的对象zxy注入给名为order1的Order实体类对象 -->
<property name="user" ref="zxy"/>
</bean>
⑧编写一个test测试方法:
⑨创建一个ClassPathXmlApplicationContext对象context然后通过context.getBean("bean的名字")获取Spring所管理的beans中的bean对象,然后输出测试结果。
看好了,我们目前是没有给order1对象进行赋值的, 然后我们新建一个order2来做对比:
public class UserTest {
public static ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
public static Order order1 = (Order) context.getBean("order1");
//新建一个Order对象然后给它赋值
public static Order test1(){
User user = new User();
user.setPassword("123456");
user.setUsername("admin");
Order order = new Order();
order.setOrderName("二号订单");
order.setUser(user);
return order;
}
public static void main(String[] args) {
//对比对象
Order order2 = new Order();
order2 = test1();
System.out.println(order1);
System.out.println(order2);
}
然后是结果:
那么到这就实现了一个简单地IOC/DI,也就是控制反转/依赖注入。
四、集合、数组属性的注入。
也就是如果说Order实体类中存的不是一个User实体类而是一个以User实体类为元素的List集合或数组arr、set或map或的话,我们要怎么注入?
没错!还是配置xml!
废话不多说,来看例子!
现在Order实体类是这样:
@Data //替换get、set方法
@AllArgsConstructor //全参构造方法
@NoArgsConstructor //无参数构造方法
@EqualsAndHashCode //equals和hashCode方法
@ToString //toString方法
@Component
public class Order {
private String[] arr;
private List<User> list;
private Set<User> set;
private Map<String,User> map;
private Properties prop;
private String orderName;
}
那么我们如果要注入相应的内容的话我们需要这样的话我们需要这样:
<bean id="order1" class="com.test.entity.Order">
<property name="orderName" value="订单一号"/>
<!-- 将实体类User的对象zxy注入给名为order1的Order实体类对象 -->
<property name="arr">
<array>
<value>123</value>
<value>456</value>
</array>
</property>
<property name="list">
<list>
<ref bean="zxy"/>
<ref bean="zxy"/>
</list>
</property>
<property name="map">
<map>
<entry key="a1" value-ref="zxy"/>
<entry key="a2" value-ref="zxy"/>
</map>
</property>
<property name="prop">
<props>
<prop key="a1">123</prop>
<prop key="a1">456</prop>
</props>
</property>
</bean>
结果:
那么问题来了,我为什么要进行IOC/DI注入?因为这样能省下在开发过程中不必要的繁琐事和减少一定的冗余代码,并且这个被注入的user对象可以在别的类对象再次中当成属性被注入,这是可以复用的!那么假设我们有很多个不同的类中的不同的类方法,都需要用到同一个完全相同类对象,我们难道要去一个一个的new新建然后赋值吗?
我知道有人还有另一个问题:
我又要去配置文件配置这个类,又要去记那这串又长又看不懂又难记的两句话我难道直接new一个不更快吗?
对啊,你们想的对!所以你们想的别人开发人员也想到了,并且解决了这个问题,所以到后期注解开发的时候,你们就会看到许多注解,举个例子:
我们后期写SSM代码当我们在一个类对象中需要用另一个类对象的方法时,我们不再是new新建一个对象,而是:@Service将这个类当成service给Spring管理然后将ShowMapper也交给Spring管理,然后通过@Autowired直接将对应的对象注入给我们目前所需要的这类对象中。
好的,那么Spring的IOC和DI就大致到一段落了,感谢大家浏览!