在Java中创建对象是通过构造方法进行创建的,如果构造方法设置为私有化防止其他人调用并(new)创建对象;
自动装配(Autowire)
其实就是为了让注入更加的简单实用了自动装配,
属性装配
类型装配
问题:为什么属性名称注入不直接通过属性名称注入,而通过反射找到set方法在找到属性注入;
解答(原因):因为属性注入只有两种注入:set方法注入和构造方法注入,所以要想属性注入就必须通过set / 构造方法进行注入;
这里的属性是注入后的实现类(接口)例如:private. UserDao. userDao。 这里 的userDao就是属性的名字
private UserDao userDao;//基于Spring注入dao 面向接口编程
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
在application.xml配置文件
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--user层-->
<bean id="user" class="com.jt.pojo.User">
<property name="id" value="100"></property>
<!-- <property name="name" value="<范冰冰>"></property>-->
<property name="name">
<value><![CDATA[<范冰冰>]]></value>
</property>
</bean>
<!--构建userdao-->
<bean id="userDao" class="com.jt.dao.UserDaoImpl"></bean>
<!--3.构建Service
自动装配: 程序无需手动的编辑property属性
autowire="byName" 根据属性的名称进行注入
1.找到对象的所有的set方法 setUserDao()
2.setUserDao~~~~set去掉~~~UserDao~~~~首字母小写~~~userDao属性
3.Spring会根据对象的属性查询自己维护的Map集合,根据userDao名称,查找Map
中的Key与之对应,如果匹配成功.则能自动调用set方法实现注入(必需有set方法)
autowire="byType" 根据类型进行查找
1.找到对象的所有的set方法 setUserDao()
2.根据set方法找到该set方法中参数的类型UserDao.class
3.Spring根据自己维护对象的Class进行匹配.如果匹配成功则实现注入(set方法)
进行量使用bytype注入,使用byname容易包空指针错误
自动装配!!!!!
-->
<bean id="userService" class="com.jt.service.com.jt.service.UserServiceImpl" autowire="byType"/>
<!--4.构建Controller-->
<bean id="userController" class="com.jt.controller.UserController" autowire="byName"/>
</beans>
controller的代码
package com.jt.controller;
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.stereotype.Controller;
public class UserController {
//spring容器负责注入Service对象
private UserService userService;
private User user; //代替用户传入的数据
public void setUser(User user) {
this.user = user;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void addUser(){
userService.addUser(user);
}
}
service层的代码
package com.jt.service;
import com.jt.pojo.User;
public interface UserService {
void addUser(User user);
}
service层的代码的实现类
package com.jt.service;
import com.jt.dao.UserDao;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
public class UserServiceImpl implements UserService{
/**
* 关于注解的说明
* 1.@Autowired: 可以根据类型/属性名称进行注入 首先按照类型进行注入
* 2.@Qualifier: 如果需要按照名称进行注入,则需要额外添加@Qualifier
* 3.@Resource(type = "xxx.class",name="属性名称")
* 关于注解补充: 由于@Resource注解 是由java原生提供的,不是Spring官方的.所以不建议使用
*/
//@Autowired
//@Qualifier(value = "属性的名称")
//@Autowired
private UserDao userDao;//基于Spring注入dao 面向接口编程
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void addUser(User user) {
String name = user.getName() + "加工数据";
user.setName(name);
userDao.addUser(user);
}
}
dao层的代码
package com.jt.dao;
import com.jt.pojo.User;
public interface UserDao {
void addUser(User user);
}
dao层的代码实现类
package com.jt.dao;
import com.jt.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
/**
* <bean id="类名首字母小写~~userDaoImpl" class="UserDaoImpl.class" />
* 如果需要修改beanId则手动添加value属性即可
*/
@Repository(value = "userDao")
public class UserDaoImpl implements UserDao{
@Override
public void addUser(User user) {
System.out.println("链接数据库执行insert into :"+user);
}
}
pojo层的代码
package com.jt.pojo;
public class User { //通过容器为对象的属性赋值
private Integer id;
private String name;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
注解模式
关于注解的说明
Spring为了简化xml配置方式,则研发注解模式.
Spring为了程序更加的严谨,通过不同的注解标识不同的层级 下面的这几种的注解作用是一样的,都是交给容器管理;
1).@Controller 用来标识Controller层的代码 相当于将对象交给Spring管理, 默认情况下是不生效的,要想生效需要在配置文件中使用包扫描
```java
<!--2.
让注解生效,开启包扫描
包路径特点: 给定包路径,则自动扫描同包及子孙包中的类
base-package: 根据指定的包路径 查找注解
写方式: 多个包路径 使用,号分隔
-->
<!--<context:component-scan base-package="com.jt.controller,com.jt.service,com.jt.dao"></context:component-scan>-->
<context:component-scan base-package="com.jt"></context:component-scan>
2).@Service 用来标识Service层代码
3).@Repository 用来标识持久层
4).@Component 万用注解
**## 编辑配置文件**
```java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!--1.构建user对象-->
<bean id="user" class="com.jt.pojo.User">
<property name="id" value="100"></property>
<property name="name">
<value><![CDATA[<范冰冰>]]></value>
</property>
</bean>
<!--业务需求1: 只想扫描@controller注解
属性说明: use-default-filters="true"
默认规则 :true 表示可以扫描其他(所有)的注解
:false 按照用户指定的注解进行加载,默认规则不生效
-->
<context:component-scan base-package="com.jt" use-default-filters="false">
<!--annotation:注解 expression:表达式指的是除了base-package=“”之外的包被扫描
include:包含指的是那个注解可以被扫描,exclude:指的是那个注解不可以被扫描
->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
<!--业务需求2: 不想扫描@controller注解-->
<context:component-scan base-package="com.jt">
<!--通过包扫描 可以加载其他的注解 排除Controller注解。 exclude:指的是这个注解不可以被扫描->
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
注解使用原理
/**
* <bean id="类名首字母小写~~userDaoImpl" class="UserDaoImpl.class" />
* 如果需要修改beanId则手动添加value属性即可
*/
@Repository(value = "userDao")
public class UserDaoImpl implements UserDao{
@Override
public void addUser(User user) {
System.out.println("链接数据库执行insert into :"+user);
}
}
使用全新的注解开发
* 关于注解的说明
* 1.@Autowired: 可以根据类型/属性名称进行注入 首先按照类型进行注入如果类型注入失败,则根据属性名称注入
* 2.@Qualifier: 如果需要按照名称进行注入,则需要添加@Qualifier和@Autowired
* * 3.@Resource(type = "xxx.class" 或 name="属性名称")
* 关于注解补充: 由于@Resource注解 是由java原生提供的,不是Spring官方的.所以不建议使用
上述的属性的注入在调用时 自动的封装了Set方法,所以Set方法可以省略不写