Узнайте, как написать пример Spring Field Injection . Инъекция поля — это тип инъекции зависимостей Spring Frameworks . В этом уроке мы напишем пару классов и увидим, как работает Field Injection Works.
Подробнее о инъекции зависимостей весной:
- Пример впрыска зависимостей пружинного установщика
- Пример инжекции зависимостей Spring Constructor
- Внедрение зависимостей Spring — Field vs Setter vs Constructor Injection
- Пружинная зависимость и инверсия управления
Внедрение зависимостей на основе полей
В этом типе внедрения зависимостей Spring присваивает зависимости непосредственно полям. Это отличается от Инъекции Конструктора или Инъекции Зависимости на основе Setter .
Интересно понять, что Spring вводит зависимости, даже если поле является приватным. Spring использует Java Reflections для этого. Следовательно, многие эксперты считают его небезопасным.
Инъекция поля, вероятно, является самой простой (но рискованной) формой инъекции зависимости . Чтобы лучше это понять, предположим, что у нас работает служба Spring Boot . Это фиктивная услуга для понимания Field Injection.
Не знаете, как написать Spring Boot Rest Service?
Прочитай это:
Spring Boot Rest Service
Хотите узнать больше о Spring Framework?
Прочитай это:
Давайте сначала напишем наш класс DogsService
Собаки Сервис
Этот класс зависит от DogsDao
. В качестве аннотированной ссылочной переменной используется @Autowired
. Есть установщик и два конструктора с соответствующими печатными сообщениями.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import com.amitph.spring.dogs.dao.DogsDao; import com.amitph.spring.dogs.repo.Dog; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; @Component public class DogsService { @Autowired private DogsDao dao; public List<Dog> getDogs() { System.out.println( "DogsService.getDogs called" ); return dao.getAllDogs(); } public void setDao(DogsDao dao) { System.out.println( "DogsService setter called" ); this .dao = dao; } public DogsService(){ System.out.println( "DogsService no-arg constructor called" ); } public DogsService(DogsDao dao) { System.out.println( "DogsService arg constructor called" ); this .dao = dao; } } |
Контроллер собак
Контроллер имеет зависимость от DogsService
. Как и в классе обслуживания, аннотация @Autowired
добавляется в ссылочную переменную. Есть сеттеры и конструкторы с печатными сообщениями.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import com.amitph.spring.dogs.repo.Dog; import com.amitph.spring.dogs.service.DogsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping ( "/dogs" ) public class DogsController { @Autowired private DogsService service; @GetMapping public List<Dog> getDogs() { return service.getDogs(); } public void setService(DogsService service) { System.out.println( "DogsController setter called" ); this .service = service; } public DogsController(){ System.out.println( "DogsController no-arg constructor called" ); } public DogsController(DogsService service) { System.out.println( "DogsController arg constructor called" ); this .service = service; } } |
Запустить код
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | ' _| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2. 1.0 .RELEASE) 2019 - 02 - 05 06 : 34 : 14.956 INFO 69421 --- [ main] com.amitph.spring.dogs.Application : Starting Application on Amits-office-mac.local with PID 69421 (/Users/aphaltankar/Workspace/personal/dog-service-jpa/out/production/classes started by aphaltankar in /Users/aphaltankar/Workspace/personal/dog-service-jpa) 2019 - 02 - 05 06 : 34 : 14.957 INFO 69421 --- [ main] com.amitph.spring.dogs.Application : No active profile set, falling back to default profiles: default 2019 - 02 - 05 06 : 34 : 15.655 INFO 69421 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode. 2019 - 02 - 05 06 : 34 : 15.711 INFO 69421 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 50ms. Found 1 repository interfaces. 2019 - 02 - 05 06 : 34 : 16.013 INFO 69421 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$EnhancerBySpringCGLIB$1cc57cd7] is not eligible for getting processed by all BeanPostProcessors ( for example: not eligible for auto-proxying) 2019 - 02 - 05 06 : 34 : 16.318 INFO 69421 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019 - 02 - 05 06 : 34 : 16.335 INFO 69421 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019 - 02 - 05 06 : 34 : 16.335 INFO 69421 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/ 9.0 . 12 2019 - 02 - 05 06 : 34 : 16.342 INFO 69421 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/aphaltankar/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.] 2019 - 02 - 05 06 : 34 : 16.429 INFO 69421 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019 - 02 - 05 06 : 34 : 16.429 INFO 69421 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1419 ms 2019 - 02 - 05 06 : 34 : 16.454 INFO 69421 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/] 2019 - 02 - 05 06 : 34 : 16.457 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2019 - 02 - 05 06 : 34 : 16.458 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2019 - 02 - 05 06 : 34 : 16.458 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'formContentFilter' to: [/*] 2019 - 02 - 05 06 : 34 : 16.458 INFO 69421 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2019 - 02 - 05 06 : 34 : 16.581 INFO 69421 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool- 1 - Starting... 2019 - 02 - 05 06 : 34 : 16.702 INFO 69421 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool- 1 - Start completed. 2019 - 02 - 05 06 : 34 : 16.830 INFO 69421 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [ name: default ...] 2019 - 02 - 05 06 : 34 : 16.906 INFO 69421 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core { 5.3 . 7 .Final} 2019 - 02 - 05 06 : 34 : 16.907 INFO 69421 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found 2019 - 02 - 05 06 : 34 : 17.059 INFO 69421 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations { 5.0 . 4 .Final} 2019 - 02 - 05 06 : 34 : 17.188 INFO 69421 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect 2019 - 02 - 05 06 : 34 : 17.783 INFO 69421 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' DogsDao no-arg constructor called DogsService no-arg constructor called DogsController no-arg constructor called 2019 - 02 - 05 06 : 34 : 18.208 INFO 69421 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019 - 02 - 05 06 : 34 : 18.244 WARN 69421 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default . Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2019 - 02 - 05 06 : 34 : 18.420 INFO 69421 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019 - 02 - 05 06 : 34 : 18.422 INFO 69421 --- [ main] com.amitph.spring.dogs.Application : Started Application in 3.878 seconds (JVM running for 4.57 ) |
Все три контроллера без аргументов вызываются последовательно. Никакие установщики или параметризованные конструкторы не были вызваны. Еще одна вещь, на которую стоит обратить внимание, — это поля, помеченные @Autowired
как частные .
Spring может устанавливать приватные поля
Spring использует отражение для установки приватных полей в нашем объекте. Это звучит полезно и, с другой стороны, небезопасно. Внедрение месторождения, его безопасность и полезность всегда обсуждались. Spring не соблюдает правила доступа к объектам. Теперь некоторые люди могут поддержать это или сказать, что Spring IoC-контейнер управляет всеми объектами и должен получить максимальный контроль над объектами.
01
02
03
04
05
06
07
08
09
10
|
@Component public class MyClass { @Autowired private DogsController controller; @Autowired private DogsService service; @Autowired private DogsDao dao; @Autowired private ApplicationProperties properties; ///// business methods } |
Как разработчик, я всегда люблю использовать Field Injection, потому что оно действительно простое и удобочитаемое. Вы можете на самом деле избежать написания методов или конструкторов- установщиков и сосредоточиться на бизнес-методах.
Резюме
Вы узнали, что Field Injection — это тип Spring Dependency Injection , и написали несколько классов, чтобы увидеть, как оно работает. Инъекция в поле проста и делает класс более читабельным. Однако, многие люди ненавидят это и избегают использовать это из-за его проблем безопасности.
В следующих разделах мы увидим подробное различие между всеми тремя: инжекцией сеттера, инжекцией поля и инжектором конструктора .
Удачного кодирования!
Смотрите оригинальную статью здесь: Spring Injection Dependency Injection Мнения, высказанные участниками Java Code Geeks, являются их собственными. |